| Superclass of Exception Classes | Notes |
| `CX_STATIC_CHECK` | - Users must handle exceptions. - Exceptions that may occur in procedures should be handled locally within the implementation or explicitly declared in the [procedure interface](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abenparameter_interface_glosry.htm) so callers know what errors to expect. - Exception classes of type `CX_STATIC_CHECK` enforce this by performing a static check at compile time. Procedure users must handle the exception locally in a `TRY` control structure or declare it in their procedure interface to propagate the exception. If not, a warning is produced. Example: - A method signature might look like this. The `RAISING` addition in method signatures declares one or more class-based exceptions that can be propagated to the caller. - When users implement the method, they are aware that an error might occur, and a specific exception can be raised. - `CX_UUID_ERROR` is a predefined exception class derived from `CX_STATIC_CHECK`. Method users should prepare their code accordingly. ```abap "Method definition using the RAISING parameter CLASS-METHODS get_uuid RETURNING VALUE(uuid) TYPE sysuuid_x16 RAISING cx_uuid_error. ... "Method implementation METHOD get_uuid. uuid = cl_system_uuid=>create_uuid_x16_static( ) . ENDMETHOD. ... "Method call: Somewhere in the code of a user that calls the method "Exception handled locally in a TRY control structure TRY. DATA(uuid) = get_uuid( ). CATCH cx_uuid_error. ... ENDTRY. "If the statement is specified without the TRY control structure, "a warning is shown. DATA(uuid2) = get_uuid( ). ``` |
| `CX_DYNAMIC_CHECK` |
- For exceptions that can be checked and avoided by preconditions:
- Unlike exception classes derived from `CX_STATIC_CHECK`, exception classes derived from `CX_DYNAMIC_CHECK` do not enforce local handling or declaration in procedure interfaces.
- However, proper exception handling is necessary when you cannot prevent the exceptions from being raised in your program logic.
- Runtime checks verify whether local handling or explicit declaration in procedure interfaces are available only if the exception is raised.
- If, at runtime, such an exception is neither locally handled nor properly declared in an interface and the exception is raised, a new exception of type `CX_SY_NO_HANDLER` is raised, with the `PREVIOUS` attribute referencing the original exception.
Example:
- The predefined class `CX_SY_ZERODIVIDE` is derived from `CX_SY_ARITHMETIC_ERROR`, which is derived from `CX_DYNAMIC_CHECK`.
- Operands in a calculation should be checked (e.g., ensuring the second operand is not 0 in a division) before performing the arithmetic operation to avoid exceptions.
```abap "Method definition using the RAISING parameter CLASS-METHODS divide IMPORTING num1 TYPE i num2 TYPE i RETURNING VALUE(div_result) TYPE decfloat34 RAISING cx_sy_zerodivide. ... "Method implementation METHOD divide. div_result = num1 / num2. ENDMETHOD. ... "Method call: Somewhere in the code of a user that calls the method "Unlike procedures specifying an exception class derived from CX_STATIC_CHECK, "procedures specifying an exception class derived from CX_DYNAMIC_CHECK do not "enforce the local handling of exceptions. So, the following statement does "not show a warning. DATA(div_result1) = divide( num1 = 5 num2 = 2 ). "Exception handled locally in a TRY control structure TRY. DATA(div_result2) = divide( num1 = 5 num2 = 0 ). CATCH cx_sy_zerodivide. ENDTRY. ``` |
| `CX_NO_CHECK` | - For errors that may occur anytime, cannot be handled locally in a meaningful way, or cannot be avoided even after a check. - An example of such an error is a lack of memory. If such exceptions were checked statically or dynamically, it would require specification in each procedure interface, which is not ideal for clear program structure. - Note that exceptions derived from `CX_NO_CHECK` are always implicitly declared in all procedure interfaces. |
| Class include | Code |
| Global class | ``` abap CLASS zcl_demo_abap DEFINITION PUBLIC FINAL CREATE PUBLIC . PUBLIC SECTION. INTERFACES if_oo_adt_classrun. PROTECTED SECTION. PRIVATE SECTION. METHODS raise_local_exception IMPORTING num TYPE i RAISING lcx_error. ENDCLASS. CLASS zcl_demo_abap IMPLEMENTATION. METHOD if_oo_adt_classrun~main. DO 6 TIMES. TRY. raise_local_exception( sy-index ). CATCH lcx_error INTO DATA(error). out->write( error->get_text( ) ). ENDTRY. ENDDO. ENDMETHOD. METHOD raise_local_exception. CASE num. WHEN 1. RAISE EXCEPTION TYPE lcx_error EXPORTING textid = lcx_error=>lcx_error. WHEN 2. RAISE EXCEPTION TYPE lcx_error EXPORTING textid = lcx_error=>some_error text = `Some error text`. WHEN 3. RAISE EXCEPTION TYPE lcx_error MESSAGE e002(zdemo_abap_messages). WHEN 4. RAISE EXCEPTION TYPE lcx_error MESSAGE e005(zdemo_abap_messages) WITH 'Some' 'error' 'occurred'. WHEN 5. RAISE EXCEPTION TYPE lcx_error MESSAGE ID 'ZDEMO_ABAP_MESSAGES' TYPE 'E' NUMBER '005' WITH 'Hello' 'world'. WHEN OTHERS. "Default message RAISE EXCEPTION TYPE lcx_error. ENDCASE. ENDMETHOD. ENDCLASS. ``` |
| Class-Relevant Local Types tab (CCDEF include) | ``` abap CLASS lcx_error DEFINITION INHERITING FROM cx_static_check. PUBLIC SECTION. INTERFACES if_t100_dyn_msg. CONSTANTS: BEGIN OF lcx_error, msgid TYPE symsgid VALUE 'ZDEMO_ABAP_MESSAGES', msgno TYPE symsgno VALUE '001', attr1 TYPE scx_attrname VALUE '', attr2 TYPE scx_attrname VALUE '', attr3 TYPE scx_attrname VALUE '', attr4 TYPE scx_attrname VALUE '', END OF lcx_error. CONSTANTS: BEGIN OF some_error, msgid TYPE symsgid VALUE 'ZDEMO_ABAP_MESSAGES', msgno TYPE symsgno VALUE '005', attr1 TYPE scx_attrname VALUE 'TEXT', attr2 TYPE scx_attrname VALUE '', attr3 TYPE scx_attrname VALUE '', attr4 TYPE scx_attrname VALUE '', END OF some_error. DATA text TYPE string READ-ONLY. METHODS constructor IMPORTING textid LIKE if_t100_message=>t100key OPTIONAL previous LIKE previous OPTIONAL text TYPE string OPTIONAL. PROTECTED SECTION. PRIVATE SECTION. ENDCLASS. ``` |
| Local Types tab (CCIMP include) | ``` abap CLASS lcx_error IMPLEMENTATION. METHOD constructor ##ADT_SUPPRESS_GENERATION. super->constructor( previous = previous ). me->text = text. CLEAR me->textid. IF textid IS INITIAL. if_t100_message~t100key = if_t100_message=>default_textid. ELSE. if_t100_message~t100key = textid. ENDIF. ENDMETHOD. ENDCLASS. ``` |