Copyright 2024 - BV TallVision IT

When a report or module dumps, the reason is mostly quite obvious. Some runtime errors are "catchable", but when not caught they will stop your report. If you are the user causing the dump, there is a "Debug" button available to you to start the debugger.

This is "Post mortum" debugging - where you know the patient has already died - but having a look around in the debugger can be very useful. Catchable runtime errors are handled with CATCH SYSTEM-EXCEPTIONS using the name of the runtime error. Here's a list of runtime errors with a brief explanation of what to look out for.

To detect semantically related runtime errors using a common name, they are combined into exception groups. You can handle catchable runtime errors in an ABAP program using the following control statements:

CATCH SYSTEM-EXCEPTIONS exc1 = rc1 ... excn = rcn.
  ...
ENDCATCH.

The expressions exc1 … excn indicate either a catchable runtime error or the name of an exception class. The expressions rc1 … rcn are numeric literals. If one of the specified runtime errors occurs between CATCH and ENDCATCH, the program does not terminate. Instead, the program jumps straight to the ENDCATCH statement. After ENDCATCH, the numeric literal rc1 … rcn that you assigned to the runtime error is contained in the return code field SY-SUBRC. The contents of any fields that occur in the statement in which the error occurred cannot be guaranteed after ENDCATCH.

If you don't know which exception class to catch, you can use OTHERSto catch all possible catchable runtime errors. Do beware: not all runtime errors are catchable !

CATCH SYSTEM-EXCEPTIONS others = 4.
  ...
ENDCATCH.

Catching the error that would cause a dump - TRY - ENDTRY

One example problem that can not be caught with CATCH SYSTEM-EXCEPTIONSis the example below:

APPEND 'MSGNR = 123' TO options.
APPEND 'ORX' TO options.  "<== ERROR HERE
APPEND 'MSGNR = 124' TO options.
* Dump: SAPSQL_WHERE_PARENTHESES
*       CX_SY_DYNAMIC_OSQL_SYNTAX

CATCH SYSTEM-EXCEPTIONS others = 4. 
  SELECT * FROM t100
    UP TO 1 ROWS
    WHERE (options).
  ENDSELECT.
ENDCATCH. 

The solution for this is the TRY - ENDTRY block, which is a much more precise version of the CATCH SYSTEM-ERRORS. The above example solved:

TRY.
    SELECT * FROM t100
      UP TO 1 ROWS
      WHERE (options).
    ENDSELECT.
  CATCH cx_sy_dynamic_osql_error.
    MESSAGE `Wrong WHERE condition!` TYPE 'I'.
ENDTRY.

The exceptions hierarchy

So which exceptions are available ? And which ones can be caught with CATCH ? Note that exceptions live in exception classes, which adhere to the naming convention CL_CX_*. There's many examples available through transaction SE24 class builder. Also note that there is a class-hierarchy on the exceptions. The top op the hierarchy is class CX_DYNAMIC_CHECK, below is you could finr e.g. CX_SY_CONVERSION_ERROR and below that the CX_SY_CONVERSION_NO_NUMBER can be found. If you want to specifically catch a number conversion error, the ...NO_NUMBER exception is your candidate of choice. It it's all possible conversion errors you are interested in catching, the .._ERROR candidate is better, and so on. This example doesn't care what exception is caught - as long as it is caught:

DATA: lv_char TYPE c LENGTH 50,
      lv_num TYPE n LENGTH 6,
      lo_error_ref TYPE REF TO cx_dynamic_check.

TRY.
    lv_num = 123.
    lv_char = 'Test'.

    lv_num = lv_char. "<= No dump (lv_num = 000000)

    IF lv_num = lv_char. "<= DUMP! - uncatchable !!
    ENDIF.

  CATCH cx_dynamic_check INTO lo_error_ref.
    MESSAGE `Conversion error` TYPE 'I'. "<= Catches nothing...
ENDTRY.

Normally the dump that is produced when a conversion error happened will also state the exception that should/could be used to CATCH it. However, there is an exception - so I found. The IF statement above produces a dump, which can not be caught.

The solution for this is a bit of leg-work. With DESCRIBE FIELD ... TYPE ... the type of the field can be determined. If it is N, the lv_CHAR variable better only contains numbers.

So SAP - why is the conversion done in an IF statement not catchable ?