Working with exceptions

Exceptions are situations that occur while an ABAP program is being executed, in which the normal continuation of the program does not make any sense. 

Exceptions can be raised either implicitly in the ABAP runtime environment or explicitly in the ABAP program

Class-Based Exceptions

Exception types 

Static Check (Local or Nearby Handling; CX_STATIC_CHECK)

If you raise an exception within a given routine, then you must either handle (CATCH) it within the routine or declare the exception class in the method signature using the RAISING keyword
The advantage of this type of exception class is that it makes it blindingly obvious to any calling programs that a certain type of problem might occur, and so the calling program is forced by the syntax check to implement some error handling code.

Demo program: DEMO_CATCH_EXCEPTION

Dynamic Check (Local or Nearby Handling; CX_DYNAMIC_CHECK)

If you raise an exception within a routine, then you must either handle it locally or pass it upwards by mentioning the exception class in the signature; if you don’t, then no syntax error occurs

No Check (Remote Handling;CX_NO_CHECK)

In most documentation, this type of exception class is described as being useful for problems that can occur anywhere (such as the system running out of memory), and it would clearly be impractical to declare a long list of such exception classes in every single method signature throughout the system.

Designing Exception Classes

Creating the Exception

Use the transaction SE24: the class ZCX_, set the superclass CX_STATIC_CHECK, the clas type is for Exception.

Declaring the Exception

...

Raising the Exception

.....
RAISE EXCEPTION TYPE ycx_one EXPORTING ... = .....
.....


DATA: lcx_one TYPE REF TO ycx_one,
            lcx_two TYPE REF TO ycx_two.
DATA: lo_exc_root TYPE REF TO cx_root.

*TRY.. ENDTRY block declares a protective section in which we can CATCH one or more exceptions. 

TRY.
do_something( ).
CATCH ycx_one INTO lcx_one.
...
CATCH ycx_two INTO lcx_two.
CATCH cx_root  INTO  lo_exc_root.
      lv_msg = lo_exc_root->get_text( ).
      WRITE: / lv_msg.
....
CLEANUP.
...
ENDTRY.

Clean Up 

The idea behind the CLEANUP construct is that at the start of any given routine, the data is in a consistent state.

Example:

class lcl_test_cleanup implementation.
 
  method run.
    try.
        inside_method( ).
      catch cx_root.
        mo_out->write( 'Ошибка перехвачена' ).
    endtry.
 
    ro_test_cleanup = me.
  endmethod.
 
  method inside_method.
    try.
        data(ls_data2) = mt_fio2[ bukrs = '0001' ].
      catch cx_sy_open_sql_db.
        "Допустим ждали эту
      cleanup.
        mo_out->write( ' CLEANUP Отработало' ).
    endtry.
 
  endmethod.
 
  method display.
    mo_out->display( ).
    ro_test_cleanup = me.
  endmethod.
 
  method constructor.
    mo_out = cl_demo_output=>new( ).
  endmethod.
 
endclass.

Error Handling with RETRY and RESUME

With the RETRY command, after the error handling in the CATCH block, the processing is restarted at the beginning of the TRY block, where the exception was raised.


TRY.
CATCH.
-> RETRY.
ENDTRY.


Example:
try.
    data(gs_data) = gt_fio[ bukrs = '0001' ].
  catch cx_root.
    append value #( pernr = '90000001' fio = 'Ivanov I.I.'  bukrs = '0001'     ) to gt_fio.
    retry.
endtry.


With the RESUME command, after the error handling in the CATCH block, the processing is restarted at the line after the line that raised the exception. If, for example, the routine being called does not know how to fix the problem but the calling program does, then the exception is raised as RESUMABLE so that the calling program can fix up the data and then come back to the point things left off in the routine being called.  The BEFORE UNWIND statement makes sure that the local variables of the called routine are preserved so that they are still available when processing restarts after the error has been fixed.
TRY,
CATCH BEFORE UNWIND cx_*.
RESUME.
ENDTRY.

Example
try.
    data(lo_exc) =  new cx_exp( ) .
    data(lo_out) = cl_demo_output=>new( )->write( 'Start' ).
    raise resumable exception lo_exc.
    lo_out->write( 'Возврат в обработку' ).
  catch  BEFORE UNWIND cx_exp.
    lo_out->write( 'Блок catch' ).
    resume.
endtry.

Exception class to use Messages from T100

To achieve and use the messages from the message repository, you need to include the interface IF_T100_MESSAGE in the exception class. This interface allows you to declare and pass the message parameters when raising the exception.


DATA: lo_exc TYPE REF TO zcx_msg_t100.
DATA: ls_t100_key TYPE scx_t100key.
*
START-OF-SELECTION.

* No additional parameter, the message would be empty
  TRY.
      RAISE EXCEPTION TYPE zcx_msg_t100.
    CATCH zcx_msg_t100 INTO lo_exc.
      MESSAGE lo_exc TYPE 'I'.
  ENDTRY.

* Specific message ID, with the parameter set
  TRY.
      RAISE EXCEPTION TYPE zcx_msg_t100
        EXPORTING
          textid    = zcx_msg_t100=>ZCX_MSG_T100
          IV_FIELD1 = 'Value1'.
    CATCH zcx_msg_t100 INTO lo_exc.
      MESSAGE lo_exc TYPE 'I'.
  ENDTRY.

* Raising with a different message
  TRY.
      ls_t100_key-msgid = '00'.
      ls_t100_key-msgno = '443'.
      RAISE EXCEPTION TYPE zcx_msg_t100
        EXPORTING
          textid = ls_t100_key.
    CATCH zcx_msg_t100 INTO lo_exc.
      MESSAGE lo_exc TYPE 'I'.
 
* getting all the attributes of the message
* like ID, class, attr1 etc
       MESSAGE ID lo_exc->IF_T100_MESSAGE~T100KEY-msgid
               TYPE 'I'
               NUMBER lo_exc->IF_T100_MESSAGE~T100KEY-msgno
               WITH   lo_exc->IF_T100_MESSAGE~T100KEY-ATTR1.
  ENDTRY.

Propagating exception 

The RAISING addition is specified in the declaration of a method:
METHODS meth ... RAISING cx_... cx_...

Exception Texts

...


IF_T100_DYN_MSG

Raises the exception CX_DEMO_DYN_T100 that includes the interface IF_T100_DYN_MSG. The addition MESSAGE passes the attributes of a message that determines the exception text.

TRY.
RAISE EXCEPTION TYPE cx_demo_dyn_t100
MESSAGE ID 'SABAPDEMOS'
TYPE 'I'
NUMBER '888'
WITH 'Message'.
CATCH cx_demo_dyn_t100 INTO DATA(oref).
cl_demo_output=>display( oref->get_text( ) &&
`, ` && oref->msgty ).
ENDTRY.



Additional information

  • https://wiki.scn.sap.com/wiki/display/ABAP/Exception+Handling+in+ABAP+object+with+the+help+of+Exception+Class

Comments