
Earlier in this learning journey, we looked at error handling using the TRY, CATCH, and ENDTRY statements. After the TRY statement comes the statement that might cause an error. If the error does occur, the system jumps to the CATCH statement and processes its contents. Whatever happens, the method carries on processing after the ENDTRY statement.

In a TRY…ENDTRY block, you can include more than one CATCH statement. This allows you to handle different exceptions differently.

You can list multiple exceptions in a single CATCH statement. In this example, the same catch block will be processed if the system triggers either cx_sy_arithmetic_error or cx_sy_zerodivide.

When you list a class in a CATCH statement, the system will process the corresponding block if an exception with that class or one of its subclasses is triggered. In this example, cx_sy_arithmetic_error is a superclass of both cx_sy_arithmetic_overflow and cx_sy_zerodivide. Conseqeuently, the block will be processed if an exception with the type of either of the subclasses is raised.

All exception classes are part of an inheritance hierarchy whose topmost superclass is the class CX_ROOT. As we have already seen, if you use a superclass in a CATCH statement, the system will jump to it if an exception with the type of any of its subclasses is triggered. Since all exception classes are subclasses of CX_ROOT, the statement CATCH CX_ROOT is sufficient to catch any exception.
Sequence of CATCH Statements

When you write CATCH statements, you must place the most specific class (or classes) first and the most generic ones last. If you place a superclass above one of its subclasses, you will cause a syntax error. This is because the system could not process the specific CATCH block because it is overshadowed by the more generic one.
The INTO Addition
Each exception is represented by an object. You can place this object in a reference variable and work with it - for example, to retrieve the error text from the exception class using the get_text( ) method as shown in the example here.

You can use an inline declaration in the CATCH statement to ensure that the reference variable is declared with the correct type.
The most common thing to do with the exception object is to call its get_text( ) method. However, exception objects can possess other attributes and methods to help you handle the error.

Exception classes can have attributes that describe more precisely what went wrong. These attributes are often used to fill the placeholders of messages. You define the attribute in the public section of the exception class with its appropriate name and type.
In order to fill the attribute when the exception is raised, you need a corresponding import parameter of the constructor of the exception class. You can generate the attribute using a quick fix. Place the cursor on the method name constructor and press Ctrl + 1. Choose the quick fix Re-generate constructor.
The Attribute "Previous"
Sometimes within a call chain a method will catch an exception. In response, it will raise a different exception for its own caller to catch. This might happen, for example, if a framework raises an exception that is too technically-oriented for the application to process by itself. However, in certain circumstances the method that does this (method 2 in the example) may want to trigger its own exception, but also pass on the first exception. It can do this using the previous attribute of the exception class.

When you raise an exception, you can pass an instance of an exception class to the importing parameter previous. This attaches the exception object to the new exception. A method that catches the second exception can access the first exception object using the public read-only attributes previous.
Previous is implemented in the superclass CX_ROOT, and is therefore available in all exception classes.

A method does not always have to handle the exceptions of another method that it has called. Instead, it can propagate the method along the call chain. Instead of using the CATCH statement to handle the exception, the method includes the RAISING clause in its definition. This indicates to the callers of the method that the exception can be passed to them.
If the exception is not caught anywhere along the call chain, a runtime error will occur.