You are on page 1of 59

ABAP workshop Exception Handling

Exception Handling
Exceptions are events (or errors) that may happen during the execution of a program that interrupts the normal flow of control Exception Handling mechanism makes it possible to deal with these run time errors appropriately, without crashing the program The key principle of exception handling is change in control flow
2

Defensive Programming
Goal of Defensive Programming is to avoid the errors in a program by considering possible errors right from the start, thereby preventing them before they occur, therefore creating Robust Programs If the program has logic to accomplish a task (example, say read a file) then the program also needs to have a mechanism to handle possible errors that may happen (file may not exist, user/system may not have enough authorization to access the file, the file may be large and system may not have sufficient memory to read the complete file, etc)

Runtime Errors
The runtime errors can be of two types
Catchable Runtime Errors which can be caught using the necessary exception handling Non-Catchable Runtime Errors which can not be caught by exceptional handling
[Catchable Runtime errors that are not caught and the Non-Catchable Runtime errors always result in termination of program or short dump]
4

Catchable Runtime Errors


Catchable Runtime Errors are of two types
Result of an error detected by the ABAP runtime system
X = 1 / 0 - results in the (automatic) runtime error of type cx_sy_zerodivide

When the programmer explicitly raises an exception to signal an error situation using the RAISE EXCEPTION command more than likely in conjunction with a IF conditional clause
5

Exceptions RAISED explicitly


Explicitly programmers can raise exception in two ways
Raise and create an exception object simultaneously using the command
RAISE EXCEPTION TYPE <EX_CLASS> [EXPORTING a1 = b1 = ]

Raise an exception with an exception object that already exists using the command
RAISE EXCEPTION exception.
6

Exceptions RAISED explicitly


Raise an exception with an exception object that already exists using the command [RAISE EXCEPTION exception] may be done because of two reasons
The exception was already created using CREATE OBJECT statement (may be rare) An exception may already have been caught, but after checking some of the attributes, the handler may have realized that it could not deal with this exception properly, and thus decided to raise it again
7

Runtime System and Explicit Exception Raising


Exception raised by runtime system Y = 0. X = 1 / Y. OR Explicit Exception raised by the code (programmer)

Y = 0. IF Y <> 0 THEN. X = 1 / Y. ELSE. RAISE EXCEPTION TYPE cx_sy_zerodivide. ENDIF.

Sample Program
REPORT ZCHAIN_EXCEPTION_3. CLASS myclass DEFINITION. PUBLIC SECTION. CLASS-METHODS main importing operand TYPE i RAISING cx_sy_arithmetic_overflow cx_sy_zerodivide. ENDCLASS. "myclass DEFINITION CLASS myclass IMPLEMENTATION. METHOD main. DATA: x TYPE i, y TYPE float, oERROR TYPE REF TO cx_root, txtError TYPE string, MYFILE TYPE STRING. TRY. X = 2147483647. X = X + 1. CATCH cx_sy_arithmetic_overflow INTO oerror. txtError = oError->get_text( ). MESSAGE ID '00' TYPE 'I' NUMBER '208' WITH txtError. ENDTRY. TRY. X = X / 0. CATCH cx_sy_zerodivide INTO oerror. txtError = oError->get_text( ). MESSAGE ID '00' TYPE 'I' NUMBER '208' WITH txtError. ENDTRY. 9

Sample Program (contined)


TRY. Y = sqrt( -1 ). CATCH CX_SY_ARG_OUT_OF_DOMAIN into oerror. txtError = oError->get_text( ). MESSAGE ID '00' TYPE 'I' NUMBER '208' WITH txtError. ENDTRY. TRY. MYFILE = 'surefiledoesnotexist.txt'. TRANSFER 'Text written to new file' TO MYFILE. CATCH CX_SY_FILE_OPEN_MODE INTO oerror. txtError = oError->get_text( ). MESSAGE ID '00' TYPE 'I' NUMBER '208' WITH txtError. ENDTRY. ENDMETHOD. "main ENDCLASS. "myclass IMPLEMENTATION START-OF-SELECTION. myclass=>main( 0 ).
10

Exception Classes
Exceptions after release 6.10 use the object oriented concept. They are represented by objects that are instances of classes. Each such class is called an exception e.g., a division by zero, data conversion etc. There is a class called cx_root which is the root of all the exception classes i.e. all other classes are inherited from this class. This class can be used to define handlers for all types of exceptions.
11

Exception Classes Examples


ADDF_INT_OVERFLOW
Overflow at addition, type I (ADD ... UNTIL / ADD ... FROM ... TO) Exception class: CX_SY_ARITHMETIC_OVERFLOW

ASSIGN_FIELD_NOT_IN_RANGE
The field is not within the RANGE specified. Exception class: CX_SY_ASSIGN_OUT_OF_RANGE

BCD_ZERODIVIDE
Division by 0 (type P) Exception class: CX_SY_ZERODIVIDE

CREATE_OBJECT_CLASS_NOT_FOUND
The class specified in the dynamic CREATE OBJECT was not found. Exception class: CX_SY_CREATE_OBJECT_ERROR

And Many Many More.


12

Exception Hierarchy
CX_ROOT

CX_STATIC_CHECK

CX_DYNAMIC_CHECK

CX_NO_CHECK

13

Exception Hierarchy (cont.)


CX_ROOT
|

CX_STATIC_CHECK |--CX_DYNAMIC_CHECK
|-| | | | | | | | | | | | | | | | | | | | | | |--CX_SY_ARITHMETIC_ERROR | | | |--CX_SY_ZERODIVIDE | | | |--CX_SY_ARITHMETIC_OVERFLOW | | | |--CX_SY_ARG_OUT_OF_DOMAIN | | | |--CX_SY_PRECISION_LOSS | |--CX_SY_ASSIGN_ERROR | |--CX_SY_CODEPAGE_CONVERTER_INIT | |--CX_SY_CONVERSION_ERROR | |--CX_SY_CREATE_ERROR | |--CX_SY_FILE_ACCESS_ERROR |--CX_SY_FIND_INFINITE_LOOP

| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |

| |--

CX_NO_CHECK

| |--CX_SY_EXPORT_NO_SHARED_MEMORY | |--CX_SY_EXPORT_BUFFER_NO_MEMORY | |--CX_SY_GENERATE_SUBPOOL_FULL

|--CX_SY_REMOTE_CALL_ERROR | | | |--CX_SY_RMC_COMM_FAILURE | | | |--CX_SY_RMC_INVALID_STATUS | | | |--CX_SY_RMC_SYSTEM_FAILURE | |--CX_SY_TOO_MANY_FILES

|--CX_SY_DYN_CALL_ERROR | | | |--CX_SY_DYN_CALL_ILLEGAL_CLASS | | | |--CX_SY_DYN_CALL_ILLEGAL_FORM | | | |--CX_SY_DYN_CALL_ILLEGAL_FUNC | | | |--CX_SY_DYN_CALL_ILLEGAL_METHOD | | | |--CX_SY_DYN_CALL_PARAMETER_ERROR | | | |--CX_SY_DYN_CALL_EXCP_NOT_FOUND | | | |--CX_SY_DYN_CALL_ILLEGAL_TYPE | | | |--CX_SY_DYN_CALL_PARAM_MISSING | | | |--CX_SY_DYN_CALL_PARAM_NOT_FOUND | |--CX_SY_FILE_ACCESS_ERROR | | | |--CX_SY_FILE_AUTHORITY | | | |--CX_SY_FILE_CLOSE | | | |--CX_SY_FILE_IO | | | |--CX_SY_FILE_OPEN | | | |--CX_SY_FILE_OPEN_MODE | | | |--CX_SY_FILE_POSITION | | | |--CX_SY_FILE_TRUNCATE

14

Catching and Handling Exceptions


Handlers are used to catch or handle the class-based exceptions Handlers are defined for statement in the TRY block using the CATCH command A handler consists of all statements between its CATCH clause and the CATCH clause of the next handler or CLEANUP command or ENDTRY if there are no more handlers.

15

Catching and Handling Exceptions (continued)


TRY. "Begin of try block Code here that may raise an exception X = 1 / 0. implicit exception Or RAISE EXCEPTION TYPE cx_sy_zerodivide. "end of try block CATCH CX_CLASS1 CX_CLASS2 CX_CLASS3 [INTO oref].
[Catch Block] Catch exceptions of Class CX_CLASS1, CX_CLASS2 and CX_CLASS3 plus the exceptions of all the subclasses.

CATCH CX_CLASS4 [INTO oref]. Catch exceptions of Class CX_CLASS4 plus the exceptions of all the subclasses. * CATCH cx_root. Catch all - For catching catchable exceptions of all kinds * " Any number of statements CLEANUP. "Cleanup block - Statements to restore consistent state ENDTRY.

16

Catching and Handling Exceptions (continued)


The coding in the TRY block defines a protected area whose exceptions can be handled in the subsequent CATCH block If no exception occurs in the TRY block and its end (i.e., ENDTRY or first CATCH statement) is reached, processing continues after the ENDTRY, except if CLEANUP block exists, in which case processing in the CLEANUP block is done before processing continues after the ENDTRY.
17

Catching and Handling Exceptions (continued)


If an exception occurs in the TRY block, the system looks for an exception handler in the same or in the outer TRY-ENDTRY control statement. The actual exception handlers consists of one or more optional CATCH blocks. These contain the program logic that is executed if the related exception occurs in the TRY block of the same TRY-ENDTRY control structure.
18

Catching and Handling Exceptions (continued)


A CATCH block handles the exceptions from the exception classes cx_class1 cx_class2 , which are specified after the CATCH statement, along with the exceptions from their respective subclasses. If the INTO addition is specified, a reference (pointer) to the exception object is stored in oref. The exception object is created automatically when an runtime exception occurs (example divide by zero occurs). oref is used to access this object and get attributes and methods that occurred. oref must be an object reference variable whose static type must be more general or equal to the most general of the specified exception classes.
19

Catching and Handling Exceptions (continued)


When the end of CATCH block is reached, processing continues after the ENDTRY, and the CLEANUP block is skipped (unlike javas finally clause). In ABAP any CATCH block executed between a TRY ENDTRY will prevent the execution of the CLEANUP block in that TRY ENDTRY block. In Future ABAP releases the class based exceptions will be able to be raised in a way that allows them to be resumable. This will enable the program execution to be resumed after the statement that raised the exception during the handling of a resumable exception.

20

Catching and Handling Exceptions (continued)


The CATCH block is not protected, which means any exceptions that occurs with the CATCH block are not caught. To catch an exception that occurs within a CATCH block, a separate (nested) TRY ENDTRY control structure must be used within the CATCH block CLEANUP block is used to give the program or specific objects a consistent status again (say be reinitializing some variables of clearing any aggregate fields programmatically.) This is necessary since the control flow of the program is generally changed when an exception occurs When in CLEANUP block the execution has to leave this block the normal way (through ENDTRY) and not prematurely by RETURN or REJECT or runtime errors occur Statements such as EXIT, CHECK, or Continue are forbidden only if they leave the CLEANUP block permanently. But if they are in a loop within the CLEANUP block they are okay
21

The raising of an exception object comprises of:

Catching and Handling Exceptions (continued)


The creation of an exception object The created exception is handled if the exception handler for that exception exists (or exception handler of exception classs immediate or any superclass exists) within the TRY ENDTRY block If the appropriate exception handler is not found within the TRY-ENDTRY block, the exception is handled by any surrounding TRY-ENDTRY block (next level) if the exception handler exists there. CLEANUP code if it exists in the first (current) TRY block is run before going to the next level The propagation of this object along the call chain until a suitable handler is found

If no handler is found, a runtime error will occur


22

Catching and Handling Exceptions (continued)


If a procedure (or even a method) is called within a TRY block, the appropriate handlers in the TRY-ENDTRY construct will also catch all the exceptions that are raised but not caught within that procedure If the procedure (or method) does not have the handler for one or more exception class(es), it should at least declare that exception using the RAISING addition, or else compilation or runtime error occurs unless appropriate type of superclass (cx_no_check, etc) is used METHOD method1 RAISING ex1 ex2 or PROCEDURE proc1 RAISING ex1 ex2
23

Selecting the Right Superclass


This syntax check and the resulting necessity to handle exceptions or forward them using a declaration in the interface is suitable for most application-specific error situations. There may, however, be exception situations to which this procedure is not suited, such as: Exceptions that can occur but that do not have to be handled or declared.
It is not worth making it compulsory to handle or explicitly forward this kind of exception, since the user can establish by means of program logic that the exception will not occur.

Resource bottlenecks
Handling or declaring all exceptions without fail would mean having to specify these exceptions in almost every interface. This would simply make the programs more illegible rather than more "robust".

Three different types of exception class have been introduced to deal with this problem:
Exceptions requiring a declaration that either have to be handled or propagated. This is the standard case described previously. Exceptions that can be declared in the interface if desired. Exceptions that must not be declared in the interface.

24

Selecting the Right Superclass (more info)


Superclass for Exceptions that have to be declared CX_STATIC_CHECK
The cx_static_check category should be chosen if you want to make sure that this exception is always dealt with and if a local exception handler has a chance to do something useful in the exceptional situation The cx_static_check is checked by both the compiler and the runtime system such that if any exception of this category occurs and is not handled locally inside of the procedure, has been declared in the RAISING clause of the procedure's interface

Superclass for Exceptions that do not have to be declared CX_DYNAMIC_CHECK


The cx_dynamic_check category should be chosen if programmers can usually avoid the occurrence of the exception beforehand; in most cases the programmers know that the exception will not be raised in their application context The cx_dynamic_check is checked only by the runtime system when exception tries to leave a procedure that it has been declared in the RAISING clause of the procedure's interface

Superclass for Exceptions that must not be declared CX_NO_CHECK


The cx_no_check should be chosen if the exception can occur almost everywhere, but most programmers do not want to deal with such exceptions (resource bottleneck, etc) The cx_no_check exception can always leave the interface of a procedure. Neither the compiler nor the runtime system performs any interface checks

25

Selecting the Right Superclass (more info)


The concept of CHECKED exceptions (cx_static_check, cx_dynamic_check and cx_no_check) enables you to find untreated exceptions at compile time or make it possible to identify the procedure that should have handled the exception. The different levels of checks avoid the counterproductive check workarounds like empty exception handlers, which would sometimes be necessary with a less flexible concept If you are in a situation where you get a cx_static_check or cx_dynamic_check exception that should have been declared as cx_no_check, do not write an empty exception handler. Throw your own exception of category cx_no_check A suitable exception handler is found if the class of the exception, or one of its superclasses, is listed in the corresponding CATCH clause. Thus any handler that looks like CATCH cx_sy_no_handler, CATCH cx_static_check, or CATCH cx_root must also be prepared to handle this kind of exception. A handler should at least write an error log in this case Subclasses (or more specific ones) should always appear in first in the CATCH sequence followed by their superclasses if required, with the cx_root if at all used should be at the end. This is because the CATCH is executed in sequential order and if cx_root happens to be on the top, it will CATCH all the exceptions, without the control even going to subclasses CATCH that may have more specific information about the exception
26

Catching and Handling Exceptions (continued)


Exception object attributes can store information about the cause of the exception situation Exception handlers need no longer know the exception context, they can get it from the exception object Inheritance enables refinement of exceptions, therefore subclasses can be created by adding new attributes and reusing existing exceptions by making them more specific
27

Propagating Exceptions in Call Hierarchy


Since procedures or (methods or subroutines used here interchangingly) can call other procedures a corresponding call hierarchy is created. If an exception is not handled in a procedure, the system attempts to propagate it to the caller of the procedure Exceptions try to leave (propagate) a procedure whenever the CATCH within the TRY-ENDTRY block(s) of that procedure cannot handle them, so that these exceptions can be handled at the caller (or its caller or callers caller, etc ) But this propagation is only possible, if that exception has been declared in the RAISING clause of the procedure's interface RAISING clause can be defined for any Method, except for a Class Constructor
28

Basic Attributes from CX_ROOT


Every exception class inherits the following attributes from CX_ROOT.
TEXTID
This is used to define different exception text for a specific exception class, this attribute is generally set by the constructor, and influences the result of the GET_TEXT method

PREVIOUS
This can contain a reference to a previous exception and enables exceptions to be chained. This helps us track the path of an exception right back to its origin.

29

Basic Methods from CX_ROOT


GET_TEXT and GET_LONGTEXT
These methods return the exception text (error message) as a character string

GET_SOURCE_POSITION
This method returns the program name of the main program, the name of any include program concerned and the line number of the raising point
30

Exception Source & Line Number


REPORT ZDEMO_EXCEPTION_LINENBR. DATA: x TYPE i, oERROR TYPE REF TO cx_root, txtError TYPE string. DATA lineno type I. DATA progname like sy-repid. TRY. x = 2147483647. x = x + 1. CATCH cx_sy_arithmetic_overflow INTO oError. txtError = oError->get_text( ). write: 'Exception was raised and caught! '. write: / 'Exception Text: '. write: txtError. Now get the source and line number. call method oError->get_source_position IMPORTING program_name = progname source_line = lineno. write: / 'Program name: ' , progname(30). write: / 'line number: ' , lineno. write: / 'Exception name: ', oError->kernel_errid. ENDTRY.

Line 12 all lines are counted, inc. blank

31

Chained Exceptions
As mentioned the PREVIOUS attribute of the CX_ROOT can contain a reference to a previous exception and enables exceptions to be chained. This helps us track the path of an exception right back to its origin.

TRY. x = 2147483647. x = x + 1. CATCH cx_sy_arithmetic_overflow INTO oError. TRY. RAISE EXCEPTION TYPE cx_sy_zerodivide EXPORTING previous = oError. CATCH cx_sy_zerodivide INTO oError. ENDTRY. ENDTRY. txtError = oError->get_text( ). should have Division by Zero Error oError = oError->PREVIOUS. txtError = oError->get_text( ). should have Overflow in Operation Error
32

Chained Exceptions (continued)


* * TRY. x = 2147483647. x = x + 1. RAISE EXCEPTION TYPE cx_sy_arithmetic_overflow CATCH cx_sy_arithmetic_overflow INTO oerror. TRY. x = x / operand. RAISE EXCEPTION TYPE cx_sy_zerodivide EXPORTING previous = oerror. CATCH cx_sy_zerodivide INTO oerror. TRY. Y = sqrt( -1 ). RAISE EXCEPTION TYPE CX_SY_ARG_OUT_OF_DOMAIN EXPORTING previous = oerror. CATCH CX_SY_ARG_OUT_OF_DOMAIN INTO oerror. TRY. MYFILE = 'surefiledoesnotexist.txt'. TRANSFER 'Text written to new file' TO MYFILE. RAISE EXCEPTION TYPE CX_SY_FILE_OPEN_MODE EXPORTING previous = oerror. CATCH CX_SY_FILE_OPEN_MODE into oerror. ENDTRY. ENDTRY. ENDTRY. ENDTRY. text_lastest = oerror->get_text( ). text_previous1 = oerror->previous->get_text( ). text_previous2 = oerror->previous->previous->get_text( ). text_previous3 = oerror->previous->previous->previous->get_text( ). WRITE: / 'Latest error: ', text_lastest, / 'Error before that: ', text_previous1, / 'Error before that: ', text_previous2, / 'Error before that: ', text_previous3.

33

Classical Exception Handling


Before release 6.10, only the following types of exception existed
Catchable runtime errors that can be handled with the CATCH SYSTEM-EXCEPTIONS Statement Self defined, non-class based exceptions that were only possible in the interfaces (signature or parameters of function or procedures not the object oriented class interface) of function or procedure modules
34

Classical Exception Handling (continued)


CATCH SYSTEM-EXCEPTIONS compute_int_zerodivide = 4. X = 1 / 0. ENDCATCH. IF sy-subrc = 4. MESSAGE 'Division by zero exception classical exception handling' TYPE 'I' DISPLAY LIKE 'E ENDIF.

35

Classical Exception Handling (continued)


CATCH SYSTEM-EXCEPTIONS compute_int_zerodivide = 4 compute_float_zerodivide = 5. int1 = 100. flt1 = '123.45'. int1 = int1 / 0. * flt1 = flt1 / 0. ENDCATCH. IF sy-subrc = 4. MESSAGE 'Division by zero (integer) exception classical exception handling' TYPE 'I' DISPLAY LIKE 'E'. ENDIF. IF sy-subrc = 5. MESSAGE 'Division by zero (floating) exception classical exception handling' TYPE 'I' DISPLAY LIKE 'E'. ENDIF.
36

Custom Exception Classes


With the help of Inheritance existing exceptions can be more specifically used by adding new attributes to it Exceptions are represented by objects that are instances of exception classes. Defining an exception is, therefore, the same as creating an exception class. All exception classes must inherit from the common superclass CX_ROOT and one of its subordinate classes CX_STATIC_CHECK, CX_DYNAMIC_CHECK or CX_NO_CHECK All exception classes must begin with the prefix CX_. They are usually defined globally with the Class Builder of the ABAP Workbench. Local exception classes can, however, also be defined
37

Local Exception Classes


Local exception classes can be defined for specific exceptions that only occur within one single ABAP program. The condition for a local exception class is that it inherits from one of the three classes CX_STATIC_CHECK, CX_DYNAMIC_CHECK, or CX_NO_CHECK, or from their subordinate classes. An individual constructor and individual attributes can be created. Individual methods should not be created, however, and the methods of superclasses should not be redefined.
38

Local Exception Classes (continued)


report DEMO_LOCAL_EXCEPTION_1. CLASS CX_LOCAL_EXCEPTION definition inheriting from CX_STATIC_CHECK. ENDCLASS. START-OF-SELECTION. TRY. raise exception type CX_LOCAL_EXCEPTION. CATCH CX_LOCAL_EXCEPTION. message Local Exception! type I. ENDTRY. This example shows a minimal local exception class, which is simply the local representation of one of the three direct subordinate classes of CX_ROOT. It can be used in the program.
39

Local Exception Classes (continued)


REPORT ZDEMO_LOCAL_EXCEPTION_2. CLASS CX_LOCAL_EXCEPTION definition inheriting from CX_STATIC_CHECK. public section. data LOCAL_TEXT type STRING. methods CONSTRUCTOR importing TEXT type STRING. ENDCLASS. CLASS CX_LOCAL_EXCEPTION implementation. METHOD CONSTRUCTOR. SUPER->CONSTRUCTOR( ). LOCAL_TEXT = TEXT. ENDMETHOD. ENDCLASS. DATA OREF type ref to CX_LOCAL_EXCEPTION. START-OF-SELECTION. TRY. raise exception type CX_LOCAL_EXCEPTION exporting TEXT = Local Exception. CATCH CX_LOCAL_EXCEPTION into OREF. message OREF->LOCAL_TEXT type I. ENDTRY. In this example, the exception class from the previous example is extended to include an individual attribute and constructor. The IMPORTING parameter of the constructor must be supplied when the exception is raised (it is required here). The attribute can be evaluated in the handler of the exception.

40

Local Exception Classes (continued)


REPORT ZDEMO_LOCAL_EXCEPTION_3. CLASS CX_LOCAL_EXCEPTION definition inheriting from CX_SY_ARITHMETIC_ERROR. public section. methods CONSTRUCTOR importing SITUATION type STRING. ENDCLASS. CLASS CX_LOCAL_EXCEPTION implementation. METHOD CONSTRUCTOR. SUPER->CONSTRUCTOR( OPERATION = SITUATION ). ENDMETHOD. ENDCLASS. DATA OREF type ref to CX_LOCAL_EXCEPTION. DATA TEXT type STRING. START-OF-SELECTION. TRY. raise exception type CX_LOCAL_EXCEPTION exporting SITUATION = START-OF-SELECTION'. CATCH CX_LOCAL_EXCEPTION into OREF. TEXT = OREF->GET_TEXT( ). message TEXT type I. ENDTRY. In this example, an exception class is derived from one of the predefined exception classes for error situations in the runtime environment. An individual constructor is defined with an individual IMPORTING parameter that supplies the superclass constructor with this parameter. When the exception is handled, the exception text, as defined in the superclass, is read with GET_TEXT.

41

Global Exception Classes


Class Builder is used to create Exception Classes (some properties in the Class Builder have been adopted by SAP development to support these) When creating Global Exception Classes ensure that it has CX_ prefix (or YCX_ or ZCX_ or /CUST/CX prefix) naming convention Choose the right category for the new Exception Class. The category is the super class of the class, defaults to CX_STATIC_CHECK class
42

Global Exception Classes (continued)


When creating an Exception Class in Class Builder, it has to be explicitly mentioned that Exception Class is being created (by selecting the Exception Class radio button) The With Message Class option facilitates the use of messages defined in the message maintenance tool (transaction SE91), placeholders (&) created here can be dynamically be populated when runtime exceptions are created using ABAP values via class attributes. Note: the Exception Class is not a class in sense of object orientation, but is a group [class] of messages created using SE91
43

Global Exception Classes (continued)


Using T-Code SE91 a message class Z_EXCEPTION_TEST is created with two messages 000 and 001 as shown below. We will use these two messages in the Exception Class [this is done this so that exceptions can show these messages]

Message Class is not an OO (Object Oriented) class, just a Group of Messages, we could theoretically have one message class and all the messages can be grouped under that class.

44

Global Exception Classes (continued)


The Exception Class [this is an actual OO class] is created as follows (T-code: SE24) and RAISED as shown in the Code. Default Exception ID is used for the TEXT

REPORT ZDEMO_GLOBAL_EXCEPTION_1. DATA OREF type ref to ZCX_C027393A. DATA s1 TYPE string. START-OF-SELECTION. TRY. raise exception type ZCX_C027393A exporting MYTOKEN = '123'. CATCH ZCX_C027393A into OREF. s1 = OREF->get_text( ). message s1 type 'I'. Use this line or next * message OREF type 'I'. ENDTRY. 45

Global Exception Classes (Using Non Default Text)


For a different message, a Non-Default Exception ID is needed (see Text named ZCX_C027393A_NEW different from ZCX_C027393A) the code needs to export the textid for this non default text along with the other attributes like MYTOKEN.
REPORT ZDEMO_GLOBAL_EXCEPTION_2. DATA OREF type ref to ZCX_C027393A. DATA s1 TYPE string. START-OF-SELECTION. TRY. raise exception type ZCX_C027393A exporting textid = ZCX_C027393A=>ZCX_C027393A_NEW MYTOKEN = '12345'. CATCH ZCX_C027393A into OREF. s1 = OREF->get_text( ). message s1 type 'I'. Use this line or next * message OREF type 'I'. ENDTRY. 46

Resumable exceptions

47

Assertions
An Assertion is the confirmation that a specific status of the data objects in a program actually exists Assertions are used to verify specific assumptions about the status of a program at a specific point and to ensure that these are maintained Unlike implementation with an IF statement and, for example, an exit message, the ASSERT statement is shorter, its meaning is instantly recognizable, and it can be activated externally
48

Assertions (continued)

49

Assertions (continued)

50

Assertions (continued)
Syntax ASSERT [ [ID group [SUBKEY sub]] [FIELDS val1 val2 ...] CONDITION ] log_exp. For log_exp, you can specify any logical expression

51

Assertions (continued)
When the program reaches an active assertion, the logical expression is evaluated and the program execution continues from the statement after ASSERT only if the result of log_exp is true At an inactive assertion, the logical condition log_exp is not evaluated and the program execution continues at the statement after ASSERT If the result of log_exp is false, for an always active assertion (without the addition ID) an untreatable exception is triggered and the program terminates with the runtime error ASSERTION_FAILED

52

Assertions (continued)
Without addition ID, the assertion is always active. When using addition ID, the activation and the behavior of the statement are controlled from outside the program by means of a checkpoint group. If the ID addition is specified, the CONDITION addition must be specified before the log_exp logical expression Addition ID assigns the assertion to a checkpoint group group (Tcode SAAB or ABAP workbench to create). You must specify the name of the checkpoint group directly and the group must exist in the repository. To administer a checkpoint group, use transaction SAAB Checkpoint can be made externally [as opposed to changing the source code] to 1) Inactive (do nothing,ignore the assert), 2) Break (start the debugger from this assert), 3) log (log the assertion in a log) 4) Abort (terminate the program with runtime error ASSERTION_FAILED)

53

Assertions (continued)
Addition SUBKEY only takes effect if the statement ASSERT writes entries to a log. When specifying SUBKEY, the content of sub is stored in the log as a subkey (helps us know the values when checking logs) Existing log entries of the same ASSERT statement are overwritten only if the subkey has the same content If SUBKEY is not specified, the subkey is initial.sub is a character-like expression position of which the first 200 characters are evaluated. An expression or function specified here is evaluated only if the assertion is active and the logical expression is false

54

Assertions (continued)
After addition FIELDS, you can specify a list val1 val2 ... of any values, except reference variables. If the statement ASSERT writes entries to a log, the content of the data objects val1 val2 ... is included into the log If an untreatable exception is triggered, the content of the first eight specified data objects is displayed in the corresponding short dump. If you switch to the ABAP debugger, the FIELDS addition has no effect
55

Assertions (continued)
The CONDITION addition triggers the logical expression. It has to be specified before log_exp if one of the other additions is specified; otherwise, it can be omitted To avoid the garbage-in garbage-out issues in functions and methods, have Assertion statement at the beginning of them and take appropriate action (notify user/terminate program/etc) if Assertions are violated
56

Checkpoint Group for Assertions


Use SAAB or ABAP workbench to create checkpoint group for assertions ABAP workbench
Right click on package -> Create -> Other(1) -> Checkpoint Group

57

Assertions (Example)
TRY. ASSERT ID ZCHECKPOINT1 SUBKEY 'mytest123' FIELDS x operand CONDITION operand <> 0. x = 1 / operand.
* The catch is still required especially if we just log the assertion CATCH cx_sy_zerodivide INTO oerror. txtError = oError->get_text( ). MESSAGE ID '00' TYPE 'I' NUMBER '208' WITH txtError.

ENDTRY.
58

Assertions (Log)

59

You might also like