ABAP Core
ABAP Developmentbeginner

ABAP Core Part 9: TRY, CATCH and Exception Handling Basics

Key takeaway

Handle errors with class-based exceptions: TRY/CATCH/CLEANUP, exception class hierarchy (static, dynamic, no-check), catching specific exceptions, getting texts, raising your own exceptions, and not swallowing errors.

Explanation

📌 KEY POINTS
✅ TRY … CATCH cx_… INTO lx_ref. … ENDTRY handles class-based exceptions (declare lx_ref TYPE REF TO cx_…).

✅ Three kinds: CX_STATIC_CHECK (must be declared/handled), CX_DYNAMIC_CHECK, CX_NO_CHECK.

✅ Catch specific exceptions first; get the text with lx->get_text( ).

⚠️ Never catch cx_root and do nothing — swallowed errors become data problems later.

━━━━━━━━━━━━━━━━━━━━
▶ WHERE WE ARE

Part 8 covered messages for users. Exceptions are the programmatic way to signal errors between code parts.

━━━━━━━━━━━━━━━━━━━━
▶ 1. TRY / CATCH / CLEANUP

TRY.

risky code
CATCH cx_sy_zerodivide INTO lx_div. " DATA lx_div TYPE REF TO cx_sy_zerodivide

handle

CATCH cx_sy_conversion_error cx_sy_arithmetic_error INTO lx_other.

handle several

CLEANUP.

free resources if the exception leaves this TRY block

ENDTRY.

Catching a superclass also catches all subclasses — order specific before general.

━━━━━━━━━━━━━━━━━━━━
▶ 2. THE EXCEPTION HIERARCHY

  • CX_ROOT — top.
  • CX_STATIC_CHECK — must be declared in the method signature (RAISING) or handled; the syntax check enforces it. Use for expected business errors the caller must handle.
  • CX_DYNAMIC_CHECK — must be declared, but the check happens at runtime; typical for system exceptions like CX_SY_ZERODIVIDE that callers can prevent.
  • CX_NO_CHECK — may occur anywhere, need not be declared (e.g. resource shortages).

━━━━━━━━━━━━━━━━━━━━
▶ 3. SYSTEM EXCEPTIONS YOU WILL MEET

CX_SY_ZERODIVIDE, CX_SY_CONVERSION_NO_NUMBER, CX_SY_ITAB_LINE_NOT_FOUND (table expression without line), CX_SY_OPEN_SQL_DB, CX_SY_REF_IS_INITIAL (null reference).

━━━━━━━━━━━━━━━━━━━━
▶ 4. RAISING YOUR OWN EXCEPTIONS

Create an exception class ZCX_FLIGHT_ERROR inheriting from CX_STATIC_CHECK, ideally with message-class texts (interface IF_T100_MESSAGE / IF_T100_DYN_MSG). Raise it with RAISE EXCEPTION TYPE zcx_flight_error EXPORTING … and declare it in the method: METHODS book_seat … RAISING zcx_flight_error.

━━━━━━━━━━━━━━━━━━━━
▶ 5. WHAT TO DO IN CATCH

  • Handle (retry, default value, alternative path), or
  • Translate to a meaningful exception for the caller (keep the original as previous = lx), or
  • Log and show a message at the UI layer.

Don't catch where you cannot do anything useful — let it propagate.

━━━━━━━━━━━━━━━━━━━━
▶ 6. EXCEPTIONS VS SY-SUBRC VS MESSAGES

  • sy-subrc: classic statements (READ TABLE, SELECT).
  • Exceptions: modern methods, table expressions, conversions.
  • Messages: user communication at the UI layer (Part 8).

━━━━━━━━━━━━━━━━━━━━
▶ STEP BY STEP

  1. Run the division and table expression examples.
  2. Create an exception class for "flight full" (static check).
  3. Raise it in a method when a flight is full; catch it in the report and show a message.

✅ CHECKPOINT: you handle and raise exceptions deliberately.

Code example

ABAP Code
REPORT zabap_core_exceptions. * ===== Custom exception class (normally a global class in SE24) =====CLASS lcx_flight_full DEFINITION INHERITING FROM cx_static_check.  PUBLIC SECTION.    DATA connid TYPE s_conn_id READ-ONLY.    METHODS constructor IMPORTING connid   TYPE s_conn_id OPTIONAL                                  previous LIKE previous OPTIONAL.    METHODS get_text REDEFINITION.ENDCLASS. CLASS lcx_flight_full IMPLEMENTATION.  METHOD constructor.    CALL METHOD super->constructor EXPORTING previous = previous.    me->connid = connid.  ENDMETHOD.  METHOD get_text.    CONCATENATE 'Flight' connid 'is fully booked' INTO result SEPARATED BY space.  ENDMETHOD.ENDCLASS. * ===== A method that raises it (static check -> must be declared) =====CLASS lcl_booking DEFINITION.  PUBLIC SECTION.    CLASS-METHODS check_seats      IMPORTING is_flight TYPE sflight      RAISING   lcx_flight_full.ENDCLASS. CLASS lcl_booking IMPLEMENTATION.  METHOD check_seats.    IF is_flight-seatsocc >= is_flight-seatsmax.      RAISE EXCEPTION TYPE lcx_flight_full EXPORTING connid = is_flight-connid.    ENDIF.  ENDMETHOD.ENDCLASS. DATA: lt_flights TYPE STANDARD TABLE OF sflight,      ls_f       TYPE sflight,      lv_avg     TYPE i,      lx_div     TYPE REF TO cx_sy_zerodivide,      lx_full    TYPE REF TO lcx_flight_full,      lx_any     TYPE REF TO cx_root,      lv_text    TYPE string. START-OF-SELECTION.* ===== System exception =====  TRY.      lv_avg = 100 / 0.    CATCH cx_sy_zerodivide INTO lx_div.      lv_text = lx_div->get_text( ).      WRITE: / 'Caught:', lv_text.  ENDTRY. * ===== Classic READ TABLE: check sy-subrc instead of catching =====  SELECT * FROM sflight INTO TABLE lt_flights UP TO 5 ROWS WHERE carrid = 'LH'.  READ TABLE lt_flights INTO ls_f INDEX 10.  IF sy-subrc <> 0.    WRITE: / 'Line 10 does not exist'.  ENDIF. * ===== Own exception: specific first, then general =====  LOOP AT lt_flights INTO ls_f.    TRY.        CALL METHOD lcl_booking=>check_seats EXPORTING is_flight = ls_f.        WRITE: / ls_f-connid, ls_f-fldate, 'seats available'.      CATCH lcx_flight_full INTO lx_full.        lv_text = lx_full->get_text( ).        WRITE: / lv_text.      CATCH cx_root INTO lx_any.                 " last resort: log, never ignore        lv_text = lx_any->get_text( ).        WRITE: / 'Unexpected:', lv_text.    ENDTRY.  ENDLOOP. * 💡 Modern syntax (7.40+): CATCH cx_sy_zerodivide INTO DATA(lx) declares the reference inline;*    lt_flights[ 10 ] raises CX_SY_ITAB_LINE_NOT_FOUND instead of setting sy-subrc.

Real project scenario

An interface wrapped its entire processing in TRY … CATCH cx_root … ENDTRY with an empty CATCH block "to avoid dumps". For months, conversion errors in incoming files were silently ignored, and hundreds of orders were never created. Nobody noticed until customers complained.
The team replaced the empty catch with specific handlers that logged each failed record to the application log with the exception text, created a static-check exception for business errors, and let unexpected exceptions dump in test to be fixed. Failed records became visible the same day.

Common mistakes

  • Empty CATCH blocks or catching cx_root without logging.
  • Catching general exceptions before specific ones.
  • Using CX_NO_CHECK for business errors callers should handle.
  • Raising exceptions without meaningful text.
  • Catching exceptions where no useful handling is possible.

Best practices

  • Catch specific exceptions and handle them meaningfully.
  • Use CX_STATIC_CHECK for expected business errors.
  • Give exception classes message-based texts.
  • Chain exceptions with previous when translating.
  • Log unexpected exceptions with context.

Interview angle

Questions: "Difference between CX_STATIC_CHECK, CX_DYNAMIC_CHECK and CX_NO_CHECK?", "What is CLEANUP for?", "How do you create your own exception?"
Strong answer: static check must be declared and is enforced by the syntax check (business errors), dynamic check is checked at runtime (preventable system errors), no check can occur anywhere; CLEANUP runs when an exception leaves the TRY block; own exceptions inherit from a CX_ class, ideally with T100 message texts, are raised with RAISE EXCEPTION TYPE and declared with RAISING. Never swallow exceptions silently.

Practice this lesson

Quick check

1. Which exception class type must be declared in a method signature and is checked by the syntax check?

2. What happens when the table expression itab[ 1 ] is used to access the first line of an internal table that currently has no entries?

3. If a class-based exception is raised inside a TRY block but no matching CATCH clause exists for that exception class in the current TRY...ENDTRY, what occurs?

Interview questions

1. An interface catches CX_ROOT around the entire file processing and ignores it. What are the risks and the correct approach?

Answer it in your own words first, then compare.

2. Describe how ABAP exceptions differ from classical sy-subrc handling and how you would design exception classes for a payments module.

Answer it in your own words first, then compare.

Practice more with Interview AI →

Reference-verified: the steps are checked against official SAP documentation and tutorials, and object and field names in the sample code are checked for consistency. The code has not been compiled or run on an SAP system by ERPClimb. Syntax marked release-dependent varies by SAP release, so check it in your own system.

More lessons in this topic

Interview questions on this topic

Related SAP topics