ABAP Keyword Documentation → ABAP Programming Guidelines → Architecture → Error Handling
Classical and Class-Based Exceptions
Other versions: 7.31 | 7.40 | 7.54
For reasons of downward compatibility, there are two options to define treatable exceptions yourself in ABAP:
- Classical Exceptions
These exceptions can only be declared in the interfaces of methods or function modules using
EXCEPTIONSand can be raised within such a procedure using the
MESSAGE RAISINGstatements. The procedure caller can use the
EXCEPTIONSaddition for the
CALL METHOD(the addition can also be used in the short form) or CALL FUNCTION statement to assign return codes for the
sy-subrcsystem field to the exceptions the caller wants to handle and evaluate them after the call.
- Class-Based Exceptions
These exceptions are defined by exception classes, from which the system may generate an exception object when an exception is raised (if a handler uses the
CATCH). A class-based exception can either cancel the current context or allow for a resume. Exceptions are raised using the RAISE EXCEPTION statement, and handling occurs using
TRYcontrol structure. Class-based exceptions can be raised in any procedures and can be further propagated by any procedures.
The coexistence of the two exception concepts is regulated as follows:
- You cannot declare classical and class-based exceptions together in the interface of a procedure. Within a processing block, you can raise either classical or class-based exceptions only.
- For reasons of interoperability, within a processing block you can handle class-based exceptions and evaluate the return values of function modules and methods using classical exceptions.
Using Class-Based Exceptions
Only raise class-based exceptions in new procedures, provided that you can dispense with classical exceptions from the technical point of view.
Self-defined classical exceptions are little more than return values. If you raise a classical exception
in a procedure using the
RAISE statement, the
system field is set according to the raised exception after the return to the calling program. The calling
program itself must always check, by querying
sy-subrc, whether an exception
occurred and react to it if required, for example, by appropriate handling or explicit forwarding to its own calling program (by raising a separate equivalent exception). This does not improve the clarity of the program.
The occurrence of class-based exceptions, however, results in a change of the program flow. They can either be handled directly or propagated upwards along the call hierarchy. In this way, not every procedure (method) has to consider every possible exception situation itself. This supports the separation of concerns within an application. Because the exception can be represented by an object of an exception class, this exception object can gather additional information on the exception situation and transport it to the handler. In contrast to classical exceptions, this can also include specific exception texts.
By default, raising an exception stops the entire current context even if the exception is handled.
However, there may be situations (mass data processing, for instance) in which a single error does not justify cancelling an entire service. For these cases, you can raise and propagate class-based exceptions as resumable
RESUMABLE). A handler can decide whether a service is canceled completely
or is resumed using the
RESUME statement, for example after a corresponding log entry has been written.
Class-based exceptions completely replace the classical exceptions for new code (of course, there are exceptions to this rule) and add resumability. Although classical exceptions on the raiser side are completely obsolete from a technical point of view, you must still consider the following for older code: Even if you have the raiser side under control, you cannot simply change older procedures over to class-based exceptions, because then you would have to adapt all usage locations.
When you call existing procedures that use classical exceptions, you must continue to handle them in
the new code. In this case, we recommend mapping the classical exceptions to equivalent class-based
exceptions by using
RAISE EXCEPTION. In this way, you achieve a class-based
error handling that is uniform to the outside. The exception situation can then be forwarded to higher call layers without each layer having to react to this situation explicitly.
Since class-based exceptions are currently not supported in remote-enabled function modules (RFM), classic exceptions still need to be implemented and handled for remote function calls (RFCs).
The following source code shows the declaration and the raising of a classical exception in a method
as well as their handling by evaluating
sy-subrc after a call of the method. This procedure infringes the above rule. .
CLASS application DEFINITION.
... oref TYPE REF TO application.
EXCEPTIONS application_error = 4 ).
IF sy-subrc <> 0.
The following source code shows the definition of an exception class, its declaration, and the raising
in a method as well as its handling using
CATCH after the call of the method in a
CLASS cx_application_error DEFINITION
INHERITING FROM cx_static_check.
RAISE EXCEPTION TYPE cx_application_error.
This simple example is perhaps not the most obvious demonstration of the great advantage of class-based exceptions over classical exceptions. However, the advantage is clearly seen in nested procedure calls and the handling of exceptions that were raised in more distant call levels.