CATCH cx1 ... cx_n.
1. ... INTO ex
Defines a handler for one or more class-based exceptions within a TRY block.
After the CATCH addition, you declare the exception classes whose exceptions will be caught and handled by the code that follows. If you declare a super-ordinate class, the exceptions of all its sub-classes will also be caught. If you declared CX_ROOT for example, all (class-based) exceptions would then be caught.
Note that you must declare exception classes in strict order, moving from the specialized to the general.
After the CATCH clause, you include the actual handler code, which can contain any ABAP statements you want. The handler code ends with the next CATCH statement, with a CLEANUP statement, or a ENDTRY, whichever comes first.
At runtime, if an exception occurs in the protected area of the assigned TRY block, the system leaves the processing block immediately and the flow of control continues at the associated handler. Whether the program flow is directly in the TRY block, or whether it is processing a method, subroutine, or function module called within the TRY block ("deep catching"), is immaterial. This contrasts with other (obsolete) exception mechanisms, which only supported flat handling.
At the end of the handler, processing continues at the statement immediately after the ENDTRY statement.
If another exception occurs while the handler code is being processed, the system leaves the
TRY block immediately and - if the code also lies in a protected
area - looks along the call hierarchy for a suitable handler. If it finds one, the program continues;
otherwise, a runtime error occurs. It is important to bear in mind that an exception in the handler
cannot be caught at the same level as the handler itself. The exception is either caught with its own
TRY block, or it is passed up the call hierarchy. The following examples are provided to clarify this:
METHOD some.
TRY.
... " Protected area
CALL
METHOD other.
CATCH CX_ROOT.
... " Handler for all exceptions
ENDTRY.
ENDMETHOD.
METHOD other.
TRY.
... " Protected area
CATCH
CX_SOME_EXCEPTION.
... " Handler for the exception CX_SOME_EXCEPTION; raises
,,,, " an exception itself
CATCH CX_ROOT.
... " Handler for all other exceptions
ENDTRY.
ENDMETHOD.
If an exception of the type
CX_SOME_EXCEPTION occurs
within the protected area of the method other, the system
immediately goes to the handler code for CX_SOME_EXCEPTION.
If another exception occurs while this handler code is being processed, the system leaves the
TRY block completely and searches for a handler at the next
level up in the call hierarchy. This means that the handler for CX_ROOT
in the method some is triggered, not the handler in the
method other. If the exceptions that occur inside the
handler are handled locally, you can encapsulate the handler in its own
TRY block. The implementation of the othermethod would then take the following form:
METHOD other.
TRY.
... " Protected area
CATCH
CX_SOME_EXCEPTION.
TRY.
... " Protected
area for the handler of ,,,,,,,,,, " CX_SOME_EXCEPTION
CATCH CX_ROOT.
... " Catch all exceptions
in the handler
ENDTRY.
CATCH CX_ROOT.
... " Handler for all remaining exceptions
ENDTRY.
ENDMETHOD.
... INTO ex
If, for example, the handler wants to access the exception object, it can store a reference to the object in the reference variable ex using the ... INTO ex addition.
Note that the variable ex must have an appropriate to store objects from all the classes declared in the CATCH clause.
The continuation of the above example shows implementations for the methods some and other:
METHOD some.
DATA: ex TYPE REF TO CX_ROOT.
TRY.
...
" Protected area
CALL METHOD other.
CATCH CX_ROOT INTO ex.
... " Handler for all exceptions
ENDTRY.
ENDMETHOD.
METHOD other.
DATA: some_ex TYPE REF TO CX_SOME_EXCEPTION,
other_ex TYPE REF TO CX_ROOT.
TRY.
... " Protected area
CATCH CX_SOME_EXCEPTION INTO some_ex.
... " Handler of CX_SOME_EXCEPTION;
raises an exception itself
CATCH CX_ROOT INTO other_ex.
... " Handler for all other exceptions
ENDTRY.
ENDMETHOD.