Sunteți pe pagina 1din 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)

3
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.

8
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_SY_DYN_CALL_ERROR
| |
|
|--CX_DYNAMIC_CHECK
| | |--CX_SY_DYN_CALL_ILLEGAL_CLASS
| | |
| | | | |--CX_SY_DYN_CALL_ILLEGAL_FORM
| |--CX_SY_ARITHMETIC_ERROR | | |
| | |
| | |--CX_SY_ZERODIVIDE | | |--CX_SY_DYN_CALL_ILLEGAL_FUNC
| | | | | |
| | |--CX_SY_ARITHMETIC_OVERFLOW | | |--CX_SY_DYN_CALL_ILLEGAL_METHOD
| | | | | |
| | |--CX_SY_ARG_OUT_OF_DOMAIN
| | | | | |--CX_SY_DYN_CALL_PARAMETER_ERROR
| | |--CX_SY_PRECISION_LOSS | | |
| | | | |--CX_SY_DYN_CALL_EXCP_NOT_FOUND
| |--CX_SY_ASSIGN_ERROR | | |
| |
| |--CX_SY_CODEPAGE_CONVERTER_INIT | | |--CX_SY_DYN_CALL_ILLEGAL_TYPE
| | | | |
| |--CX_SY_CONVERSION_ERROR | | |--CX_SY_DYN_CALL_PARAM_MISSING
| | | | |
| |--CX_SY_CREATE_ERROR | | |--CX_SY_DYN_CALL_PARAM_NOT_FOUND
| |
| |--CX_SY_FILE_ACCESS_ERROR | |
… | |--CX_SY_FILE_ACCESS_ERROR
• | |--CX_SY_FIND_INFINITE_LOOP | | |
| | |--CX_SY_FILE_AUTHORITY
|-- CX_NO_CHECK |
|
| |
| |--CX_SY_FILE_CLOSE
|
|--CX_SY_EXPORT_NO_SHARED_MEMORY | | |
| | | |--CX_SY_FILE_IO
|--CX_SY_EXPORT_BUFFER_NO_MEMORY | | |
| | | |--CX_SY_FILE_OPEN
|--CX_SY_GENERATE_SUBPOOL_FULL
… | | |
|--CX_SY_REMOTE_CALL_ERROR | | |--CX_SY_FILE_OPEN_MODE
| | | | |
| |--CX_SY_RMC_COMM_FAILURE | | |--CX_SY_FILE_POSITION
| |
| |--CX_SY_RMC_INVALID_STATUS | | |
| | | | |--CX_SY_FILE_TRUNCATE
| |--CX_SY_RMC_SYSTEM_FAILURE
|
|--CX_SY_TOO_MANY_FILES

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 java’s 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
Catching and Handling Exceptions
(continued)
• The raising of an exception object comprises of:
– The creation of an exception object
– The created exception is handled if the exception
handler for that exception exists (or exception handler
of exception class’s 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
caller’s 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. Line 12 – all lines are counted, inc. blank
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.

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 (T-
code 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

S-ar putea să vă placă și