Professional Documents
Culture Documents
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
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
Raise an exception with an exception object that already exists using the command
RAISE EXCEPTION exception.
6
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
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
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
Exception Hierarchy
CX_ROOT
CX_STATIC_CHECK
CX_DYNAMIC_CHECK
CX_NO_CHECK
13
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_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
15
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
20
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
25
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
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
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
33
35
40
41
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
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
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
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