Skip to Main Content

APEX

Announcement

For appeals, questions and feedback about Oracle Forums, please email oracle-forums-moderators_us@oracle.com. Technical questions should be asked in the appropriate category. Thank you!

How to Correctly Trap PL/SQL Errors for APEX

Joseph UpshawAug 14 2012 — edited Aug 15 2012
This is probably a simple fix but, I have been at it for a while and can't seem to find the magic combination.

I have a page process that calls back end PL/SQL. I have a page item that is populated by said PL/SQL procedure, P35_PROCESSING_MSG. As you know the Process allows me to specify a message for Success and another for Failure. My desire is that, if there is a back end failure, the error will display in the dialog area, using the built-in "Process Error Message" functionality. Instead, after execution, the page item still has its default value and the following, ugly, error displays in the tabular report region.
report error:
ORA-20001: Error fetching column value: ORA-01403: no data found
ORA-06510: PL/SQL: unhandled user-defined exception
I just don't get why it displays here instead of in the usual failure area. Moreover, I don't understand why the error is "*+unhandled+* user-defined exception" when, as you will see, I have handled it.

I have a page process to perfom custom MRD for a tabular form. (I don't think this is really germane to the more generic issue but, I bring it up as an explanaintion for the following code sample). I am diliberately causing a DIVIDE BY ZERO error to test the error handling form the back end.
    PROCEDURE PROCESS_MARGIN_CALL_DELETES( as_StatusMsg OUT VARCHAR2 )   
    IS
        lb_InnerErrorOccured    BOOLEAN := FALSE;
        
        ln_DeleteTargetCnt      NUMBER := 0;
        ln_DeleteTargetRow      NUMBER := 0;

    BEGIN

        ln_DeleteTargetCnt := apex_application.g_f01.COUNT;        

        FOR ln_DeleteTargetIndx IN 1..ln_DeleteTargetCnt
        LOOP

            ln_DeleteTargetRow := apex_application.g_f01(ln_DeleteTargetIndx);

            BEGIN

                If ( apex_application.g_f14.EXISTS(ln_DeleteTargetRow) ) Then
                
select 1/0 into ln_DeleteTargetCnt from dual;
                    DELETE FROM RISKDM2.INTRADAY_ECS_RSKALYST_MRGCALL
                    WHERE RISK_MARGCALL_ID = apex_application.g_f14(ln_DeleteTargetRow);
                      
                End If;                      

            EXCEPTION
               WHEN OTHERS THEN
               
                    as_StatusMsg := as_StatusMsg || SQLERRM; 
                    lb_InnerErrorOccured := TRUE;
                     
            END;

        END LOOP;

        If ( lb_InnerErrorOccured = TRUE ) Then
            RAISE INNER_EXCEPTION;     
        Else
            as_StatusMsg := 'Successfully Processed';                   
        End If;

    EXCEPTION 

        WHEN INNER_EXCEPTION THEN        
            RAISE_APPLICATION_ERROR( -20001, as_StatusMsg );

        WHEN OTHERS THEN

            as_StatusMsg := as_StatusMsg || SQLERRM; 
            RAISE_APPLICATION_ERROR( -20000, as_StatusMsg );
            
    END; 
The associated code in APEX is short and sweet:
BEGIN
   MBRDATA.MEMBER_MGR.PROCESS_MARGIN_CALL_DELETES( :P35_PROCESSING_MSG );
EXCEPTION
   WHEN OTHERS THEN
      RAISE_APPLICATION_ERROR( -20002, :P35_PROCESSING_MSG );
END;
What I am missing?

-Joe
Comments
Locked Post
New comments cannot be posted to this locked post.
Post Details
Locked on Sep 12 2012
Added on Aug 14 2012
20 comments
16,193 views