From bc3eb31a8bfd4c118acf336cd490836222a4a9c8 Mon Sep 17 00:00:00 2001
From: danrega <16720986+danrega@users.noreply.github.com>
Date: Fri, 20 Dec 2024 16:58:32 +0100
Subject: [PATCH] Update
---
27_Exceptions.md | 1335 +------------------------------------
28_Regular_Expressions.md | 12 +-
2 files changed, 20 insertions(+), 1327 deletions(-)
diff --git a/27_Exceptions.md b/27_Exceptions.md
index e42213a..7bed9b1 100644
--- a/27_Exceptions.md
+++ b/27_Exceptions.md
@@ -1456,1331 +1456,14 @@ ENDTRY.
## Executable Example
-> **💡 Note**
-> - The executable example ...
-> - includes the following artifacts:
-> - one executable class
-> - two self-defined example exception classes (one implements the `IF_T100_DYN_MSG`, the other implements `IF_T100_MESSAGE`)
-> - one message class with 5 message texts that are used as exception texts
-> - explores syntax described and uses code snippets in the cheat sheet.
-> - does not represent best practice implementations. It only focuses on demonstrating ABAP syntax.
-> - [Disclaimer](./README.md#%EF%B8%8F-disclaimer)
-
-Expand the following collapsible section for example code. To try it out, create the following artifacts
-
-- a class named `zcl_some_class`
-- an exception class named `zcx_demo_abap_error_a`
-- an exception class named `zcx_demo_abap_error_b`
-- a message class named `zdemo_abap_messages`
-
-and paste the code into it. After activation, choose *F9* for `zcl_some_class` in ADT to execute the class. The example is set up to display output in the console.
-
-
- 🟢 Click to expand for example code
-
-
-
-
-1. Create a class named `zcl_some_class` and copy and paste the code. Do not activate it yet as it contains artifacts that are still to be created. Activate all classes after the creation of the third class.
-
-
-```abap
-CLASS zcl_some_class DEFINITION
- PUBLIC
- FINAL
- CREATE PUBLIC .
-
- PUBLIC SECTION.
- INTERFACES if_oo_adt_classrun.
-
- CLASS-METHODS meth_a
- IMPORTING num TYPE i
- RAISING zcx_demo_abap_error_a.
-
- CLASS-METHODS meth_b
- IMPORTING num TYPE i
- RAISING zcx_demo_abap_error_b.
-
- CLASS-METHODS meth_resumable
- IMPORTING num1 TYPE i
- num2 TYPE i
- RETURNING VALUE(div_result) TYPE string
- RAISING RESUMABLE(zcx_demo_abap_error_b).
-
- CLASS-METHODS divide
- IMPORTING num1 TYPE i
- num2 TYPE i
- RETURNING VALUE(div_result) TYPE decfloat34
- RAISING cx_sy_zerodivide.
-
- CLASS-METHODS get_uuid
- RETURNING VALUE(uuid) TYPE sysuuid_x16
- RAISING cx_uuid_error.
-
- PROTECTED SECTION.
- PRIVATE SECTION.
-ENDCLASS.
-
-CLASS zcl_some_class IMPLEMENTATION.
- METHOD if_oo_adt_classrun~main.
-
- "------------------------------------------------------------------
- "------------------- Exception Categories -------------------------
- "------------------------------------------------------------------
-
- out->write( `------------------- Exception Categories -------------------` ).
-
- "Method specifying an exception class that inherits from CX_DYNAMIC_CHECK
-
- "No explicit exception handling required
- "The following statement does not show a syntax warning.
- DATA(div_result1) = divide( num1 = 5 num2 = 2 ).
- out->write( data = div_result1 name = `div_result1` ).
-
- TRY.
- DATA(div_result2) = divide( num1 = 5 num2 = 0 ).
- CATCH cx_sy_zerodivide.
- out->write( `Exception caught` ).
- ENDTRY.
-
- "Method specifying an exception class that inherits from CX_STATIC_CHECK
-
- "Explicit exception handling required
- "The following statement (commented in) shows a syntax warning.
- "DATA(uuid1) = get_uuid( ).
-
- TRY.
- DATA(uuid2) = get_uuid( ).
- CATCH cx_uuid_error.
- ENDTRY.
-
- out->write( repeat( val = `-` occ = 100 ) ).
-
- "----------------------------------------------------------------------------
- "------------------- Raising Class-Based Exceptions -------------------------
- "----------------------------------------------------------------------------
-
- out->write( `------------------- Raising Class-Based Exceptions -------------------` ).
- "Note: The examples show a selection. More additions are available.
- "Some are demonstrated further down.
-
- "RAISE EXCEPTION statements
-
- "RAISE EXCEPTION statement with the TYPE addition, specifying
- "the name of a visible exception class; an exception
- "object is created (if necessary, see the ABAP Keyword Documentation
- "for more details)
- TRY.
- RAISE EXCEPTION TYPE cx_sy_zerodivide.
- CATCH cx_sy_zerodivide.
- ENDTRY.
-
- "RAISE EXCEPTION statement specifying an exception object (an object
- "reference variable pointing to an exception class)
- DATA(exc) = NEW cx_sy_zerodivide( ).
- TRY.
- RAISE EXCEPTION exc.
- CATCH cx_sy_zerodivide.
- ENDTRY.
-
- "Creating an exception object inline using the NEW operator
- TRY.
- RAISE EXCEPTION NEW cx_sy_zerodivide( ).
- CATCH cx_sy_zerodivide.
- ENDTRY.
-
- "Note: Instances of abstract classes cannot be created. So, the
- "following statements are not possible.
- "RAISE EXCEPTION NEW cx_sy_arithmetic_error( ).
- "RAISE EXCEPTION NEW cx_static_check( ).
- "RAISE EXCEPTION NEW cx_dynamic_check( ).
- "RAISE EXCEPTION NEW cx_no_check( ).
- "RAISE EXCEPTION NEW cx_root( ).
-
- "Dynamic creation of an exception object with CREATE OBJECT
- DATA dyn_exc TYPE REF TO cx_root.
- CREATE OBJECT dyn_exc TYPE ('CX_SY_ZERODIVIDE').
- TRY.
- RAISE EXCEPTION dyn_exc.
- CATCH cx_root.
- ENDTRY.
-
- "COND/SWITCH operators with THROW addition
- "THROW addition in conditional expressions with the COND and SWITCH operators
- "enabling raising class-based exceptions in operand positions
- "The addition works like RAISE EXCEPTION TYPE statements.
-
- "COND operator
- DATA(int1) = 1.
- DATA(int2) = 0.
- "The example considers ABAP "allowing" zero division when both operands are 0.
- TRY.
- DATA(res1) = COND decfloat34( WHEN ( int1 <> 0 AND int2 <> 0 ) OR ( int1 = 0 AND int2 <> 0 ) THEN int1 / int2
- ELSE THROW cx_sy_zerodivide( ) ).
- CATCH cx_sy_zerodivide.
- ENDTRY.
-
- "SWITCH operator
- "The following example shows SWITCH with the THROW addition
- "and uses cx_sy_zerodivide for demonstration purposes.
- DO.
- TRY.
- DATA(num) = SWITCH #( sy-index
- WHEN 1 THEN `one`
- WHEN 2 THEN `two`
- WHEN 3 THEN `three`
- WHEN 4 THEN `four`
- ELSE THROW cx_sy_zerodivide( ) ).
- out->write( num ).
- CATCH cx_sy_zerodivide.
- out->write( `Exception caught` ).
- EXIT.
- ENDTRY.
- ENDDO.
-
- out->write( repeat( val = `-` occ = 100 ) ).
-
- "----------------------------------------------------------------------------
- "------------------- Excursions with TRY control structures -----------------
- "----------------------------------------------------------------------------
-
- out->write( `------------ Excursions with TRY control structures ------------` ).
-
- "TRY control structures are meant for handling catchable exceptions locally
- "The example shows divisions. The predefined exception class cx_sy_zerodivide
- "as suitable exception class is used.
- "If the exception is not handled, the program is terminated and the runtime
- "error COMPUTE_INT_ZERODIVIDE occurs.
- "The third calculation is not carried out because the statement block is
- "left due to the previous erroneous 0 division.
-
- TRY.
- DATA(div1) = 4 / 2.
- out->write( data = div1 name = `div1` ).
- out->write( |\n| ).
-
- DATA(div2) = 4 / 0.
- out->write( data = div2 name = `div2` ).
- out->write( |\n| ).
-
- DATA(div3) = 9 / 3.
- out->write( data = div3 name = `div3` ).
- out->write( |\n| ).
-
- CATCH cx_sy_zerodivide.
- out->write( `0 division. The exception was caught.` ).
- out->write( |\n| ).
- ENDTRY.
-
- "It is possible to specify multiple exception classes in a list and
- "multiple CATCH blocks.
- "Note: If there are multiple CATCH blocks for exceptions that are in an inheritance
- "relationship, you must pay attention that the more special exceptions are specified
- "before the more general ones.
- "The calculation example shows multiple CATCH blocks that themselves have more than
- "one exception class specified. Here, local exception classes are specified just for
- "demonstration purposes. They are not relevant in this TRY control structure.
-
- DATA int_itab TYPE TABLE OF i WITH EMPTY KEY.
-
- "Filling internal table of type i as basis for calculations
- int_itab = VALUE #( ( 5 ) ( 0 ) ( 987654321 ) ).
-
- LOOP AT int_itab ASSIGNING FIELD-SYMBOL().
- TRY.
- out->write( |--- Calculations with { } ---| ).
- DATA(calc1) = CONV decfloat34( 1 / ).
- out->write( data = calc1 name = `calc1` ).
- out->write( |\n| ).
- DATA(calc2) = ipow( base = exp = 2 ).
- out->write( data = calc2 name = `calc2` ).
- out->write( |\n| ).
- CATCH cx_sy_arithmetic_overflow .
- out->write( `Arithmetic overflow. The exception was caught.` ).
- CATCH cx_sy_zerodivide .
- out->write( `0 division. The exception was caught.` ).
- ENDTRY.
- out->write( |\n| ).
- ENDLOOP.
-
- "The following example shows a catchable exception that is
- "raised if a line is not found when using table expressions.
- DATA(str_table) = VALUE string_table( ).
- TRY.
- DATA(line_tab) = str_table[ 12345 ].
-
- "The predefined exception class cx_sy_itab_line_not_found
- "as suitable exception class is used here.
- "If the exception is not handled, the program is terminated
- "and the runtime error ITAB_LINE_NOT_FOUND occurs.
- CATCH cx_sy_itab_line_not_found.
- out->write( `The line was not found. The exception was caught.` ).
- ENDTRY.
-
- "In the following CATCH block, the predefined exception class cx_sy_arithmetic_error
- "is specified. Both cx_sy_zerodivide and cx_sy_arithmetic_overflow are derived from
- "cx_sy_arithmetic_error which is an exception class higher up in the inheritance
- "tree. Hence, cx_sy_arithmetic_error can be specified and handle both exceptions, too.
- "The following example is basically the same as above. However, only one exception
- "class is specified.
-
- LOOP AT int_itab ASSIGNING FIELD-SYMBOL().
- TRY.
- out->write( |--- Calculations with { } ---| ).
- calc1 = 1 / .
- out->write( data = calc1 name = `calc1` ).
- out->write( |\n| ).
- calc2 = ipow( base = exp = 2 ).
- out->write( data = calc2 name = `calc2` ).
- out->write( |\n| ).
- CATCH cx_sy_arithmetic_error.
- out->write( `Arithmetic error. The exception was caught.` ).
- ENDTRY.
- out->write( |\n| ).
- ENDLOOP.
-
- "Example demonstrating the exception root class cx_root specifying after CATCH to
- "catch all catchable exception.
- DO 3 TIMES.
- TRY.
- CASE sy-index.
- WHEN 1.
- RAISE EXCEPTION TYPE cx_sy_zerodivide.
- WHEN 2.
- RAISE EXCEPTION TYPE cx_uuid_error.
- WHEN 3.
- RAISE EXCEPTION TYPE cx_sy_itab_line_not_found.
- ENDCASE.
- CATCH cx_root.
- "Instead of explicit specification of potential exception classes involved
- "CATCH cx_sy_zerodivide cx_uuid_error cx_sy_itab_line_not_found.
- ENDTRY.
- ENDDO.
-
- "Evaluating exception information (get_text method)
-
- "You can use the addition INTO plus an object reference variable to store
- "a reference to an exception object. It is, for example, relevant to
- "determine the exact exception.
- "The following example is the same as above using the more general exception
- "class cx_sy_arithmetic_error. You can carry out certain tasks, for
- "example, retrieving and displaying the exception text. To retrieve exception
- "texts, you can call, for example, the method get_text.
-
- DATA exception TYPE REF TO cx_root.
-
- LOOP AT int_itab ASSIGNING FIELD-SYMBOL().
- TRY.
- out->write( |--- Calculations with { } ---| ).
- calc1 = 1 / .
- out->write( data = calc1 name = `calc1` ).
- out->write( |\n| ).
- calc2 = ipow( base = exp = 2 ).
- out->write( data = calc2 name = `calc2` ).
- out->write( |\n| ).
- CATCH cx_sy_arithmetic_error INTO exception.
- "Note:
- "- The object reference variable is of type cx_root.
- "- You could also create the variable inline, e. g. ... INTO DATA(exc).
-
- "Retrieving and displaying exception text
- DATA(exception_text) = exception->get_text( ).
-
- out->write( data = exception_text name = `exception_text` ).
- ENDTRY.
- out->write( |\n| ).
- ENDLOOP.
-
- "As above, the following example demonstrates an exception class for
- "arithmetic operations that is higher up in the inheritance tree and
- "catches zero division and arithmetic overflow errors.
- DO 2 TIMES.
- TRY.
- IF sy-index = 1.
- DATA(div) = CONV decfloat34( 1 / 0 ).
- ELSE.
- DATA(powers) = ipow( base = 10 exp = 100 ).
- ENDIF.
- CATCH cx_sy_arithmetic_error INTO DATA(error_arithm).
- DATA(text) = error_arithm->get_text( ).
- "Using RTTI to retrieve the relative name of the class
- DATA(cl_name) = CAST cl_abap_classdescr(
- cl_abap_typedescr=>describe_by_object_ref( error_arithm ) )->get_relative_name( ).
-
- out->write( text ).
- out->write( cl_name ).
- ENDTRY.
- ENDDO.
-
- "Demonstrating the instance attribute 'previous' with
- "nested TRY control structures.
- "Consider the following scenario: A method is called and
- "an exception is raised. Once evaluated, another exception
- "is raised, and the previous exception (i.e. a reference to
- "the previous exception object) is passed on to the caller.
- "The caller can then evaluate the exceptions raised.
- "The following example includes nested TRY control structures.
- "In CATCH blocks, further exceptions are raised. There, the
- "exception object is passed. In a WHILE loop, several pieces
- "of information are retrieved, including the use of RTTI.
- "Once the information has been retrieved, the previous attribute
- "is used to assign the previous exception object. Note the cast.
-
- DATA info TYPE string_table.
-
- TRY.
- TRY.
- TRY.
- RAISE EXCEPTION NEW cx_sy_zerodivide( ).
- CATCH cx_sy_zerodivide INTO DATA(err1).
- RAISE EXCEPTION NEW cx_sy_arithmetic_overflow( previous = err1 ).
- ENDTRY.
- CATCH cx_sy_arithmetic_overflow INTO DATA(err2).
- RAISE EXCEPTION NEW cx_sy_itab_line_not_found( previous = err2 ).
- ENDTRY.
- CATCH cx_sy_itab_line_not_found INTO DATA(err3).
- ENDTRY.
-
- DATA(acc_err) = CAST cx_root( err3 ).
- WHILE acc_err IS BOUND.
- DATA(txt) = acc_err->get_text( ).
-
- acc_err->get_source_position(
- IMPORTING
- program_name = DATA(prog_name)
- include_name = DATA(incl_name)
- source_line = DATA(src_line) ).
-
- "Using RTTI to gather more information on the exception
- "See the Dynamic Programming cheat sheet about RTTI.
- DATA(tdo) = CAST cl_abap_classdescr( cl_abap_typedescr=>describe_by_object_ref( acc_err ) ).
- DATA(cl_relative_name) = tdo->get_relative_name( ).
- DATA(attributes) = tdo->attributes.
- DATA(superclass) = tdo->get_super_class_type( )->get_relative_name( ).
-
- "Populating the info table
- APPEND |--------------- { sy-index } ---------------| TO info.
- APPEND |Text: { txt }| TO info.
- APPEND |Position of raised exception: { prog_name } / { incl_name } / { src_line }| TO info.
- APPEND |Exception class name: { cl_relative_name }| TO info.
- APPEND |Superclass of exception class: { superclass }| TO info.
-
- "Using the 'previous' attribute to assign the previous exception
- "object
- acc_err = acc_err->previous.
- "If there was no cast to cx_root, a cast would be required here,
- "for example, as follows.
- "acc_err = CAST #( acc_err->previous ).
- ENDWHILE.
-
- out->write( data = info name = `info` ).
-
- out->write( repeat( val = `-` occ = 100 ) ).
-
- "-----------------------------------------------------
- "------------------- CLEANUP -------------------------
- "-----------------------------------------------------
-
- out->write( `------------ CLEANUP ------------` ).
-
- "The following example shows nested TRY control structures.
- "The inner TRY control structure includes a CLEANUP block.
- "The example demonstrates that an exception raised cannot
- "be handled by the TRY control structure where it is raised.
- "No meaningful 'cleanup' action is performed in the example's
- "CLEANUP block. For demonstration purposes, an info table is
- "populated demonstrating the execution of the block.
-
- DATA info_tab TYPE string_table.
- DATA cleanup TYPE REF TO cx_root.
- DO 2 TIMES.
- APPEND |---- Loop pass { sy-index } ----| TO info_tab.
- TRY.
- TRY.
-
- IF sy-index = 1.
- DATA(calc) = CONV decfloat34( 1 / 0 ).
- ELSE.
- DATA(strtab) = VALUE string_table( ( `a` ) ( `b` ) ( `c` ) ).
- DATA(line_4) = strtab[ 4 ].
- ENDIF.
-
- CATCH cx_sy_zerodivide INTO cleanup.
- APPEND `---- Catching cx_sy_zerodivide ----` TO info_tab.
- APPEND cleanup->get_text( ) TO info_tab.
-
- CLEANUP.
- APPEND `#### Executing CLEANUP block ####` TO info_tab.
- APPEND `d` TO strtab.
-
- "CLEANUP block must be executed completely
- "Leaving the block prematurely causes a runtime error. If it is statically known
- "that it is not possible to return to the block, a syntax error is shown.
- "So, the following statement is not allowed in the CLEANUP block.
- "RETURN.
- ENDTRY.
- CATCH cx_sy_itab_line_not_found INTO cleanup.
- APPEND `---- Catching cx_sy_itab_line_not_found ----` TO info_tab.
- APPEND cleanup->get_text( ) TO info_tab.
- ENDTRY.
- ENDDO.
-
- out->write( data = info_tab name = `info_tab` ).
- out->write( |\n| ).
- out->write( |\n| ).
-
- "CLEANUP ... INTO
- "The example is the same as above. Here, the CLEANUP statement is specified
- "with the addition INTO. If required, you can evaluate the exception information
- "as shown above.
-
- DATA info_tab_b TYPE string_table.
- DATA cleanup_b TYPE REF TO cx_root.
- DO 2 TIMES.
- APPEND |---- Loop pass { sy-index } ----| TO info_tab_b.
- TRY.
- TRY.
-
- IF sy-index = 1.
- DATA(calc_b) = CONV decfloat34( 1 / 0 ).
- ELSE.
- DATA(strtab_b) = VALUE string_table( ( `a` ) ( `b` ) ( `c` ) ).
- DATA(line_4_b) = strtab_b[ 4 ].
- ENDIF.
-
- CATCH cx_sy_zerodivide INTO cleanup_b.
- APPEND `---- Catching cx_sy_zerodivide ----` TO info_tab_b.
- APPEND cleanup_b->get_text( ) TO info_tab_b.
-
- CLEANUP INTO cleanup_b.
- APPEND `#### Executing CLEANUP block ####` TO info_tab_b.
- "Using RTTI to find out the absolute name of the class of the raised execption
- DATA(class_name) = cl_abap_classdescr=>get_class_name( p_object = cleanup_b ).
- APPEND class_name TO info_tab_b.
- APPEND `d` TO strtab_b.
-
- "CLEANUP block must be executed completely
- "Leaving the block prematurely causes a runtime error. If it is statically known
- "that it is not possible to return to the block, a syntax error is shown.
- "So, the following statement is not allowed in the CLEANUP block.
- "RETURN.
- ENDTRY.
- CATCH cx_sy_itab_line_not_found INTO cleanup_b.
- APPEND `---- Catching cx_sy_itab_line_not_found ----` TO info_tab_b.
- APPEND cleanup_b->get_text( ) TO info_tab_b.
- ENDTRY.
- ENDDO.
-
- out->write( data = info_tab_b name = `info_tab_b` ).
-
- out->write( repeat( val = `-` occ = 100 ) ).
-
- "---------------------------------------------------
- "------------------- RETRY -------------------------
- "---------------------------------------------------
-
- out->write( `------------ RETRY ------------` ).
-
- "The following example includes a division of 1 by another number.
- "In a DO loop 1 is divided by all numbers from 10 to -10.
- "When the zero division exception is caught, the exception cause is
- "removed by changing the first operand's value to 0, too, before the
- "RETRY statement. The RETRY statement triggers the execution of the TRY
- "control structure again, now resulting in 0 as division result. After
- "that, and to have a self-contained example, the operand value is changed
- "back to 1.
- DATA division_result_tab TYPE TABLE OF decfloat34 WITH EMPTY KEY.
- DATA(number1) = 1.
- DATA(number2) = 11.
- DATA division_result TYPE decfloat34.
- DO.
- number2 -= 1.
- TRY.
- division_result = number1 / number2.
- APPEND division_result TO division_result_tab.
- CATCH cx_sy_zerodivide.
- "Removing the exception cause by setting a value that
- "does not raise the zero division exception
- number1 = 0.
- DATA(retry_flag) = abap_true.
- "Processing the TRY control structure again
- RETRY.
- ENDTRY.
-
- "Resetting of number1 value to 1
- IF retry_flag = abap_true.
- number1 = 1.
- retry_flag = abap_false.
- ENDIF.
-
- IF sy-index = 21.
- EXIT.
- ENDIF.
- ENDDO.
-
- out->write( data = division_result_tab name = `division_result_tab` ).
-
- out->write( repeat( val = `-` occ = 100 ) ).
-
- "----------------------------------------------------
- "------------------- RESUME -------------------------
- "----------------------------------------------------
-
- out->write( `------------ RESUME ------------` ).
-
- DATA restab TYPE string_table.
- TYPES ty_inttab TYPE TABLE OF i WITH EMPTY KEY.
- DATA(inttab) = REDUCE ty_inttab( INIT tab = VALUE ty_inttab( )
- FOR i = -5 UNTIL i > 5
- NEXT tab = VALUE #( BASE tab ( i ) ) ).
-
- LOOP AT inttab INTO DATA(wa).
- TRY.
- DATA(divres) = meth_resumable(
- num1 = sy-tabix
- num2 = wa
- ).
- APPEND |{ sy-tabix } / { wa } = { divres }| TO restab.
- CATCH BEFORE UNWIND zcx_demo_abap_error_b INTO DATA(error_resume).
- DATA(is_resumable) = error_resume->is_resumable.
- IF is_resumable IS NOT INITIAL.
- APPEND |Exception raised. Is resumable? -> "{ is_resumable }"| TO restab.
- RESUME.
- ENDIF.
- ENDTRY.
- ENDLOOP.
-
- out->write( data = restab name = `restab` ).
-
- out->write( repeat( val = `-` occ = 100 ) ).
-
- "-----------------------------------------------------
- "------------------- MESSAGE -------------------------
- "-----------------------------------------------------
-
- out->write( `------------ MESSAGE ------------` ).
-
- "The following examples demonstrate several MESSAGE statements.
- TYPES c50 TYPE c LENGTH 50.
- DATA message_attribute_tab TYPE TABLE OF c50 WITH EMPTY KEY.
-
- MESSAGE e001(zdemo_abap_messages) INTO DATA(msg).
-
- DATA(msgid) = sy-msgid.
- DATA(msgty) = sy-msgty.
-
- message_attribute_tab = VALUE #( BASE message_attribute_tab ( msgid ) ( msgty ) ( '--------' ) ).
-
- MESSAGE e004(zdemo_abap_messages)
- WITH 'A' 'B' 'C' 'D'
- INTO msg.
-
- msgid = sy-msgid.
- msgty = sy-msgty.
- DATA(msgv1) = sy-msgv1.
- DATA(msgv2) = sy-msgv2.
- DATA(msgv3) = sy-msgv3.
- DATA(msgv4) = sy-msgv4.
-
- message_attribute_tab = VALUE #( BASE message_attribute_tab ( msgid ) ( msgty ) ( msgv1 )
- ( msgv2 ) ( msgv3 ) ( msgv4 )
- ( '--------' ) ).
-
- MESSAGE ID 'ZDEMO_ABAP_MESSAGES'
- TYPE 'E'
- NUMBER '005'
- WITH 'E' 'F' 'G' 'H'
- INTO msg.
-
- msgid = sy-msgid.
- msgty = sy-msgty.
- msgv1 = sy-msgv1.
- msgv2 = sy-msgv2.
- msgv3 = sy-msgv3.
- msgv4 = sy-msgv4.
-
- message_attribute_tab = VALUE #( BASE message_attribute_tab ( msgid ) ( msgty ) ( msgv1 )
- ( msgv2 ) ( msgv3 ) ( msgv4 ) ).
-
- out->write( data = message_attribute_tab name = `message_attribute_tab` ).
- out->write( |\n| ).
-
- "Getting all messages of a message class
- "Note: When a message class/number is not found, the type
- "is put in first position followed by the specified message
- "name. Message numbers have a three-digit number.
- DATA messages TYPE string_table.
- DO 999 TIMES.
- MESSAGE ID 'ZDEMO_ABAP_MESSAGES'
- TYPE 'E'
- NUMBER sy-index
- INTO DATA(msg_of_msgcl).
-
- FIND PCRE `^E:ZDEMO_ABAP_MESSAGES` IN msg_of_msgcl.
- IF sy-subrc <> 0.
- APPEND |Message number { sy-index }: "{ msg_of_msgcl }"| TO messages.
- ENDIF.
- ENDDO.
-
- out->write( data = messages name = `messages` ).
-
- out->write( repeat( val = `-` occ = 100 ) ).
-
- "----------------------------------------------------------------------------
- "------------------- Syntax Variants of RAISE EXCEPTION/THROW ---------------
- "----------------------------------------------------------------------------
-
- out->write( `------------ Syntax Variants of RAISE EXCEPTION/THROW ------------` ).
- "In the example, the RAISE EXCEPTION/THROW statements are implemented in a method.
- "Depending on a value, specific statements are called.
-
- TYPES: BEGIN OF exception_info,
- idx TYPE i,
- exc_text TYPE string,
- BEGIN OF source_position,
- prog TYPE syrepid,
- incl TYPE syrepid,
- source_line TYPE i,
- END OF source_position,
- END OF exception_info,
- ty_tab_exception_info TYPE TABLE OF exception_info WITH EMPTY KEY.
- DATA tab_exception_info TYPE ty_tab_exception_info.
-
- "Exception class implementing interface if_t100_message
- DO.
- TRY.
- APPEND VALUE #( idx = sy-index ) TO tab_exception_info REFERENCE INTO DATA(line).
- meth_a( sy-index ).
- CATCH zcx_demo_abap_error_a INTO DATA(error_a).
- line->exc_text = error_a->get_text( ).
- error_a->get_source_position(
- IMPORTING
- program_name = line->source_position-prog
- include_name = line->source_position-incl
- source_line = line->source_position-source_line ).
- ENDTRY.
- IF sy-index = 20.
- EXIT.
- ENDIF.
- ENDDO.
-
- out->write( data = tab_exception_info name = `tab_exception_info` ).
-
- CLEAR tab_exception_info.
-
- "Exception class implementing interface if_t100_dyn_message
- DO.
- TRY.
- APPEND VALUE #( idx = sy-index ) TO tab_exception_info REFERENCE INTO line.
- meth_b( sy-index ).
- CATCH zcx_demo_abap_error_b INTO DATA(error_b).
- line->exc_text = error_b->get_text( ).
- error_b->get_source_position(
- IMPORTING
- program_name = line->source_position-prog
- include_name = line->source_position-incl
- source_line = line->source_position-source_line ).
- ENDTRY.
- IF sy-index = 15.
- EXIT.
- ENDIF.
- ENDDO.
-
- out->write( data = tab_exception_info name = `tab_exception_info` ).
-
- out->write( repeat( val = `-` occ = 100 ) ).
-
- "--------------------------------------------------------
- "------------------- Excursions -------------------------
- "--------------------------------------------------------
-
- out->write( `------------ Excursions ------------` ).
-
- "Exploring the inheritance tree of exception classes
- DATA inheritance_tree TYPE string_table.
-
- DATA(class_name_table) = VALUE string_table( ( `CX_SY_ZERODIVIDE` )
- ( `CX_SY_ITAB_LINE_NOT_FOUND` )
- ( `CX_SY_CONVERSION_OVERFLOW` )
- ( `CX_SY_RTTI_TYPE_NOT_RELEASED` )
- ( `CX_ROOT` )
- ( `CX_STATIC_CHECK` )
- ( `CL_ABAP_TABLEDESCR` ) "Excursion: Not an exception class; class name of an RTTI class
- ( `CX_THIS_CLASS_DOES_NOT_EXIST` )
- ).
-
- LOOP AT class_name_table INTO DATA(classname).
- DO.
- TRY.
-
- cl_abap_typedescr=>describe_by_name( EXPORTING p_name = classname
- RECEIVING p_descr_ref = DATA(tdo_type)
- EXCEPTIONS type_not_found = 4 ) .
- IF sy-subrc <> 0.
- APPEND `--- Class not found ---` TO inheritance_tree.
- EXIT.
- ELSE.
- APPEND classname TO inheritance_tree.
- DATA(tdo_cl) = CAST cl_abap_classdescr( tdo_type ).
- ENDIF.
-
- "This method uses classic exceptions
- tdo_cl->get_super_class_type(
- RECEIVING p_descr_ref = DATA(tdo_super_class)
- EXCEPTIONS super_class_not_found = 4 ).
-
- IF sy-subrc <> 0.
- EXIT.
- ELSE.
- classname = tdo_super_class->get_relative_name( ).
- ENDIF.
-
- CATCH cx_sy_rtti_type_not_released.
- APPEND `--- Class not released ---` TO inheritance_tree.
- EXIT.
- ENDTRY.
- ENDDO.
-
- out->write( `-------------------` ).
- out->write( data = inheritance_tree name = `inheritance_tree` ).
- CLEAR inheritance_tree.
- ENDLOOP.
-
- out->write( |\n| ).
- out->write( |\n| ).
- "Exploration down the inheritance tree (from superclass to subclasses)
- "You can use the XCO library. The example only uses examples with few
- "subclasses and classes not high up in an inheritance tree to reduce
- "the program runtime.
- class_name_table = VALUE string_table( ( `CX_SY_ZERODIVIDE` )
- ( `CX_SY_RTTI_NO_CHECK` )
- ( `CL_ABAP_TYPEDESCR ` ) "Excursion: Not an exception class; class name of an RTTI class
- ( `CX_THIS_CLASS_DOES_NOT_EXIST` )
- ).
-
- LOOP AT class_name_table INTO classname.
- DATA(xco_handler) = xco_cp_abap=>class( CONV sxco_ao_object_name( classname ) ).
- IF xco_handler->exists( ).
- "Getting the names of the subclasses
- DATA(subclass_names) = xco_handler->subclasses->all->get_names( ).
- IF subclass_names IS INITIAL.
- out->write( data = |The class { classname } has no subclasses.| ).
- ELSE.
- out->write( data = subclass_names name = `subclass_names` ).
- ENDIF.
- out->write( `-------------------` ).
- ELSE.
- out->write( |The class { classname } does not exist.| ).
- ENDIF.
- ENDLOOP.
-
- out->write( |\n| ).
- out->write( |\n| ).
-
- "Evaluating the return value of a non-class-based exception and raising a class-based exception
- TRY.
- cl_abap_typedescr=>describe_by_name( EXPORTING p_name = 'CL_THAT_DOES_NOT_EXIST'
- RECEIVING p_descr_ref = DATA(tdo_ty)
- EXCEPTIONS type_not_found = 4 ).
-
- IF sy-subrc <> 0.
- RAISE EXCEPTION TYPE zcx_demo_abap_error_b MESSAGE e005(zdemo_abap_messages) WITH 'Type not found'.
- ELSE.
- DATA(tdo_class) = CAST cl_abap_classdescr( tdo_ty ).
-
- "Getting more type information; find more details in the Dynamic Programming cheat sheet
- ...
- ENDIF.
- CATCH zcx_demo_abap_error_b INTO DATA(err).
- DATA(error_text) = err->get_text( ).
- out->write( data = error_text name = `error_text` ).
- ENDTRY.
-
- out->write( repeat( val = `-` occ = 100 ) ).
-
- "----------------------------------------------------------------------------
- "------------------- Programmatically Raising Runtime Erros -------------------------
- "----------------------------------------------------------------------------
-
- out->write( `------------ Programmatically Raising Runtime Erros ------------` ).
-
- out->write( `Obviously, the statements raising a runtime error are commented out :)` ).
-
-
- "RAISE SHORTDUMP TYPE cx_sy_zerodivide.
-
- DATA(flag) = abap_true.
- "DATA(cond_w_throw_shortdump) = COND #( WHEN flag IS INITIAL THEN `works`
- " ELSE THROW SHORTDUMP zcx_demo_abap_error_b( ) ).
-
- "DATA(switch_w_throw_shortdump) = SWITCH #( flag WHEN '' THEN `works`
- " ELSE THROW SHORTDUMP zcx_demo_abap_error_b( ) ).
-
-
- DATA(number) = 0.
- ASSERT number IS INITIAL.
- ASSERT number > -1.
- number = 1.
- ASSERT number = 1.
-
- flag = abap_false.
- "ASSERT flag = abap_true.
- ENDMETHOD.
-
- METHOD meth_resumable.
-
- IF num2 = 0 AND num1 <> 0.
- RAISE RESUMABLE EXCEPTION TYPE zcx_demo_abap_error_b.
- div_result = `No result. Resumed!`.
- ELSE.
- div_result = num1 / num2.
- ENDIF.
-
- "Statement with COND operator using RESUMABLE
- "div_result = COND #( WHEN num2 = 0 AND num1 <> 0 THEN num1 / num2
- " ELSE THROW RESUMABLE zcx_demo_abap_error( ) ).
-
- ENDMETHOD.
-
- METHOD meth_a.
- "Note: A selection of additions is covered.
-
- DATA(flag) = 'X'.
-
- CASE num.
- WHEN 1.
- "TYPE addition
- "Raises an exception of a specified exception class
- RAISE EXCEPTION TYPE zcx_demo_abap_error_a.
- WHEN 2.
- "TYPE addition including EXPORTING
- "Assigns actual parameters to input parameters of the instance constructor
- "particularly for classes implementing if_t100_message. The example uses
- "a constant structure having the same name as the exception class.
- RAISE EXCEPTION TYPE zcx_demo_abap_error_a
- EXPORTING
- textid = zcx_demo_abap_error_a=>zcx_demo_abap_error_a.
- WHEN 3.
- "Assigning values to replace placeholders of a message
- "In this case, replacing the placeholders &1 and &2 in a message.
- RAISE EXCEPTION TYPE zcx_demo_abap_error_a
- EXPORTING
- textid = zcx_demo_abap_error_a=>error_003
- p_003_a = `a`
- p_003_b = `b`.
-
- WHEN 4.
- "Assigning values to replace placeholders of a message
- "In this case, not all available parameters are filled.
- RAISE EXCEPTION TYPE zcx_demo_abap_error_a
- EXPORTING
- textid = zcx_demo_abap_error_a=>error_004
- p_004_a = `c`
- p_004_b = `d`
- p_004_c = `e`.
-
- WHEN 5.
- "Specifying an exception object
- DATA(cx_oref) = NEW zcx_demo_abap_error_a( textid = zcx_demo_abap_error_a=>error_005
- p_005_a = `Some`
- p_005_b = `error` ).
-
- RAISE EXCEPTION cx_oref.
- WHEN 6.
- "Eexception object created inline
- RAISE EXCEPTION NEW zcx_demo_abap_error_a( textid = zcx_demo_abap_error_a=>error_004
- p_004_a = `f`
- p_004_b = `g` ).
-
- WHEN 7.
- "MESSAGE addition
- "For passing message specification to an exception object
- "Note that EXPORTING can also be specified
- "After MESSAGE, a message type is specified (which is not of relevance in ABAP for Cloud
- "Development). These types can be the following: A, E, I, S, W, or X. See the ABAP Keyword
- "Documentation for information.For example, E representing an error message.
- "The character is followed by the message number. The message class name is directly
- "specified within a pair of parentheses.
- RAISE EXCEPTION TYPE zcx_demo_abap_error_a MESSAGE e002(zdemo_abap_messages).
-
- WHEN 8.
- "Specifying a message number that does not exist
- "The specified message type, message class, and message number are
- "used as short text in uppercase letters and separated by a colon
- RAISE EXCEPTION TYPE zcx_demo_abap_error_a MESSAGE e999(zdemo_abap_messages).
- WHEN 9.
- "MESSAGE, ID, TYPE, NUMBER additions
- "The message class, the message type, and the message number are specified.
- "Here, literals are specified. The example is an alternative to the one above.
-
- "addition WITH not supported when interface not implemented
- RAISE EXCEPTION TYPE zcx_demo_abap_error_a
- MESSAGE ID 'ZDEMO_ABAP_MESSAGES'
- TYPE 'E'
- NUMBER '002'.
-
- WHEN 10.
- "Specifying the values using data objects, not as literals as above.
- "Note that uppercase letters are expected.
- DATA(msgid) = 'ZDEMO_ABAP_MESSAGES'.
- DATA(msgty) = 'E'.
- DATA(msgnum) = '002'.
-
- RAISE EXCEPTION TYPE zcx_demo_abap_error_a MESSAGE ID msgid TYPE msgty NUMBER msgnum.
-
- WHEN 11.
- "Intentionally using lowercase letters for demonstration purposes
- msgid = to_lower( 'ZDEMO_ABAP_MESSAGES' ).
- msgty = 'E'.
- msgnum = '002'.
- RAISE EXCEPTION TYPE zcx_demo_abap_error_a MESSAGE ID msgid TYPE msgty NUMBER msgnum.
-
- WHEN 12.
- "Using COND operator with various additions
- DATA(cond_w_throw_1) = COND #( WHEN flag IS INITIAL THEN `works`
- ELSE THROW zcx_demo_abap_error_a( ) ).
-
- WHEN 13.
- DATA(cond_w_throw_2) = COND #( WHEN flag IS INITIAL THEN `works`
- ELSE THROW zcx_demo_abap_error_a( textid = zcx_demo_abap_error_a=>error_004
- p_004_a = `cond_a`
- p_004_b = `cond_b` ) ).
- WHEN 14.
- DATA(cond_w_throw_3) = COND #( WHEN flag IS INITIAL THEN `works`
- ELSE THROW zcx_demo_abap_error_a( MESSAGE e005(zdemo_abap_messages)
- p_005_a = `An exception raised with COND` ) ).
- WHEN 15.
- DATA(cond_w_throw_4) = COND #( WHEN flag IS INITIAL THEN `works`
- ELSE THROW zcx_demo_abap_error_a( MESSAGE ID 'ZDEMO_ABAP_MESSAGES' TYPE 'E' NUMBER '002' ) ).
-
- WHEN 16.
- DATA(cond_w_throw_5) = COND #( WHEN flag IS INITIAL THEN `works`
- ELSE THROW zcx_demo_abap_error_a( MESSAGE ID 'ZDEMO_ABAP_MESSAGES'
- TYPE 'E'
- NUMBER '005'
- p_005_a = `An exception raised with COND`
- p_005_b = `additions MESSAGE ID/TYPE/NUMBER` ) ).
-
- WHEN 17.
- "Using SWITCH operator with various additions
- DATA(switch_w_throw_1) = SWITCH #( flag WHEN '' THEN `works`
- ELSE THROW zcx_demo_abap_error_a( ) ).
- WHEN 18.
-
- DATA(switch_w_throw_2) = SWITCH #( flag WHEN '' THEN `works`
- ELSE THROW zcx_demo_abap_error_a( textid = zcx_demo_abap_error_a=>error_004
- p_004_a = `switch_a`
- p_004_b = `switch_b` ) ).
- WHEN 19.
- DATA(switch_w_throw_4) = SWITCH #( flag WHEN '' THEN `works`
- ELSE THROW zcx_demo_abap_error_a( MESSAGE e005(zdemo_abap_messages)
- p_005_a = `An exception raised with SWITCH` ) ).
-
-
- WHEN 20.
-
- DATA(switch_w_throw_3) = SWITCH #( flag WHEN '' THEN `works`
- ELSE THROW zcx_demo_abap_error_a( MESSAGE ID 'ZDEMO_ABAP_MESSAGES'
- TYPE 'E'
- NUMBER '005'
- p_005_a = `An exception raised with SWITCH`
- p_005_b = `additions MESSAGE ID/TYPE/NUMBER` ) ).
-
- WHEN OTHERS.
- RETURN.
- ENDCASE.
- ENDMETHOD.
-
- METHOD meth_b.
- "Note: A selection of additions is covered.
-
- DATA(flag) = 'X'.
-
- CASE num.
- WHEN 1.
- RAISE EXCEPTION TYPE zcx_demo_abap_error_b.
- WHEN 2.
- RAISE EXCEPTION TYPE zcx_demo_abap_error_b MESSAGE e002(zdemo_abap_messages).
- WHEN 3.
- RAISE EXCEPTION TYPE zcx_demo_abap_error_b
- MESSAGE ID 'ZDEMO_ABAP_MESSAGES'
- TYPE 'E'
- NUMBER '002'.
- WHEN 4.
- RAISE EXCEPTION TYPE zcx_demo_abap_error_b MESSAGE e005(zdemo_abap_messages) WITH 'Hello' 'world'.
- WHEN 5.
- RAISE EXCEPTION TYPE zcx_demo_abap_error_b MESSAGE ID 'ZDEMO_ABAP_MESSAGES'
- TYPE 'E'
- NUMBER '004'
- WITH 'abc' 'def' 'ghi' 'jkl'.
- WHEN 6.
- RAISE EXCEPTION TYPE zcx_demo_abap_error_b MESSAGE ID 'ZDEMO_ABAP_MESSAGES'
- TYPE 'E'
- NUMBER '005'
- WITH 'Message raised at/by'
- cl_abap_context_info=>get_system_date( )
- cl_abap_context_info=>get_system_time( )
- cl_abap_context_info=>get_user_alias( ).
-
- WHEN 7.
- RAISE EXCEPTION TYPE zcx_demo_abap_error_b MESSAGE ID 'ZDEMO_ABAP_MESSAGES'
- TYPE 'E'
- NUMBER '005'
- WITH 'only two out of four' 'parameters specified'.
- WHEN 8.
-
- MESSAGE e002(zdemo_abap_messages) INTO DATA(msg).
- RAISE EXCEPTION TYPE zcx_demo_abap_error_b USING MESSAGE.
-
- WHEN 9.
-
- MESSAGE e005(zdemo_abap_messages) WITH 'a' 'b' 'c' 'd' INTO msg.
- RAISE EXCEPTION TYPE zcx_demo_abap_error_b USING MESSAGE.
-
- WHEN 10.
-
- DATA: mid TYPE sy-msgid VALUE 'ZDEMO_ABAP_MESSAGES',
- mtype TYPE sy-msgty VALUE 'E',
- msg_num TYPE sy-msgno VALUE '002'.
-
- MESSAGE ID mid TYPE mtype NUMBER msg_num INTO msg.
- RAISE EXCEPTION TYPE zcx_demo_abap_error_b USING MESSAGE.
-
- WHEN 11.
- "The following statements have the same effect as USING MESSAGE.
- MESSAGE ID 'ZDEMO_ABAP_MESSAGES'
- TYPE 'E'
- NUMBER '004'
- WITH 'mno' 'pqr' 'stu' 'vwx'
- INTO msg.
-
- "Explictly passing the sy values
- RAISE EXCEPTION TYPE zcx_demo_abap_error_b MESSAGE ID sy-msgid
- TYPE sy-msgty
- NUMBER sy-msgno
- WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
-
- WHEN 12.
- DATA(cond_w_throw_1) = COND #( WHEN flag IS INITIAL THEN `works`
- ELSE THROW zcx_demo_abap_error_b( MESSAGE e005(zdemo_abap_messages)
- WITH `An exception raised with COND,` `MESSAGE/WITH additions` ) ).
-
- WHEN 13.
- MESSAGE e005(zdemo_abap_messages) WITH 'Exception raised with COND,' 'USING MESSAGE addition' INTO msg.
-
- DATA(cond_w_throw_2) = COND #( WHEN flag IS INITIAL THEN `works`
- ELSE THROW zcx_demo_abap_error_b( USING MESSAGE ) ).
-
- WHEN 14.
- DATA(switch_w_throw_1) = SWITCH #( flag WHEN '' THEN `works`
- ELSE THROW zcx_demo_abap_error_b( MESSAGE e005(zdemo_abap_messages)
- WITH `An exception raised with SWITCH,` `MESSAGE/WITH additions` ) ).
-
- WHEN 15.
- MESSAGE e005(zdemo_abap_messages) WITH 'Exception raised with SWITCH,' 'USING MESSAGE addition' INTO msg.
-
- DATA(switch_w_throw_2) = SWITCH #( flag WHEN '' THEN `works`
- ELSE THROW zcx_demo_abap_error_b( USING MESSAGE ) ).
-
- WHEN OTHERS.
- RETURN.
- ENDCASE.
- ENDMETHOD.
-
- METHOD divide.
- div_result = num1 / num2.
- ENDMETHOD.
-
- METHOD get_uuid.
- uuid = cl_system_uuid=>create_uuid_x16_static( ) .
- ENDMETHOD.
-
-ENDCLASS.
-```
-
-2. Create another class named `zcx_demo_abap_error_a`. This is an exception class. In this example, do not create it by specifying a superclass in the ADT wizard. Activate all classes after the creation of the third class.
-
-```abap
-CLASS zcx_demo_abap_error_a DEFINITION
- PUBLIC
- INHERITING FROM cx_dynamic_check
- FINAL
- CREATE PUBLIC .
-
- PUBLIC SECTION.
-
- INTERFACES if_t100_message.
-
- CONSTANTS message_class TYPE symsgid VALUE 'ZDEMO_ABAP_MESSAGES'.
-
- CONSTANTS:
- BEGIN OF zcx_demo_abap_error_a,
- msgid TYPE symsgid VALUE message_class,
- msgno TYPE symsgno VALUE '001',
- attr1 TYPE scx_attrname VALUE '',
- attr2 TYPE scx_attrname VALUE '',
- attr3 TYPE scx_attrname VALUE '',
- attr4 TYPE scx_attrname VALUE '',
- END OF zcx_demo_abap_error_a.
-
- CONSTANTS:
- BEGIN OF error_002,
- msgid TYPE symsgid VALUE message_class,
- msgno TYPE symsgno VALUE '002',
- attr1 TYPE scx_attrname VALUE '',
- attr2 TYPE scx_attrname VALUE '',
- attr3 TYPE scx_attrname VALUE '',
- attr4 TYPE scx_attrname VALUE '',
- END OF error_002.
-
- CONSTANTS:
- BEGIN OF error_003,
- msgid TYPE symsgid VALUE message_class,
- msgno TYPE symsgno VALUE '003',
- attr1 TYPE scx_attrname VALUE 'P_003_A',
- attr2 TYPE scx_attrname VALUE 'P_003_B',
- attr3 TYPE scx_attrname VALUE '',
- attr4 TYPE scx_attrname VALUE '',
- END OF error_003.
-
- CONSTANTS:
- BEGIN OF error_004,
- msgid TYPE symsgid VALUE message_class,
- msgno TYPE symsgno VALUE '004',
- attr1 TYPE scx_attrname VALUE 'P_004_A',
- attr2 TYPE scx_attrname VALUE 'P_004_B',
- attr3 TYPE scx_attrname VALUE 'P_004_C',
- attr4 TYPE scx_attrname VALUE 'P_004_D',
- END OF error_004.
-
- CONSTANTS:
- BEGIN OF error_005,
- msgid TYPE symsgid VALUE message_class,
- msgno TYPE symsgno VALUE '005',
- attr1 TYPE scx_attrname VALUE 'P_005_A',
- attr2 TYPE scx_attrname VALUE 'P_005_B',
- attr3 TYPE scx_attrname VALUE 'P_005_C',
- attr4 TYPE scx_attrname VALUE 'P_005_D',
- END OF error_005.
-
- DATA p_003_a TYPE string.
- DATA p_003_b TYPE string.
- DATA p_004_a TYPE string.
- DATA p_004_b TYPE string.
- DATA p_004_c TYPE string.
- DATA p_004_d TYPE string.
- DATA p_005_a TYPE string.
- DATA p_005_b TYPE string.
- DATA p_005_c TYPE string.
- DATA p_005_d TYPE string.
-
- METHODS constructor
- IMPORTING
- textid LIKE if_t100_message=>t100key OPTIONAL
- previous LIKE previous OPTIONAL
- p_003_a TYPE string OPTIONAL
- p_003_b TYPE string OPTIONAL
- p_004_a TYPE string OPTIONAL
- p_004_b TYPE string OPTIONAL
- p_004_c TYPE string OPTIONAL
- p_004_d TYPE string OPTIONAL
- p_005_a TYPE string OPTIONAL
- p_005_b TYPE string OPTIONAL
- p_005_c TYPE string OPTIONAL
- p_005_d TYPE string OPTIONAL
- .
- PROTECTED SECTION.
- PRIVATE SECTION.
-ENDCLASS.
-
-
-
-CLASS zcx_demo_abap_error_a IMPLEMENTATION.
-
-
- METHOD constructor ##ADT_SUPPRESS_GENERATION.
-
- super->constructor( previous = previous ).
-
- me->p_003_a = p_003_a.
- me->p_003_b = p_003_b.
- me->p_004_a = p_004_a.
- me->p_004_b = p_004_b.
- me->p_004_c = p_004_c.
- me->p_004_d = p_004_d.
- me->p_005_a = p_005_a.
- me->p_005_b = p_005_b.
- me->p_005_c = p_005_c.
- me->p_005_d = p_005_d.
-
- CLEAR me->textid.
- IF textid IS INITIAL.
- if_t100_message~t100key = if_t100_message=>default_textid.
- ELSE.
- if_t100_message~t100key = textid.
- ENDIF.
- ENDMETHOD.
-ENDCLASS.
-```
-
-3. Create another class named `zcx_demo_abap_error_b`. This is an exception class. In this example, do not create it by specifying a superclass in the ADT wizard. Activate all classes after the creation of this class.
-
-
-```abap
-CLASS zcx_demo_abap_error_b DEFINITION
- PUBLIC
- INHERITING FROM cx_static_check
- FINAL
- CREATE PUBLIC .
-
- PUBLIC SECTION.
-
- INTERFACES if_t100_message.
- INTERFACES if_t100_dyn_msg.
-
- METHODS constructor
- IMPORTING
- textid LIKE if_t100_message=>t100key OPTIONAL
- previous LIKE previous OPTIONAL.
- PROTECTED SECTION.
- PRIVATE SECTION.
-ENDCLASS.
-
-
-
-CLASS zcx_demo_abap_error_b IMPLEMENTATION.
- METHOD constructor ##ADT_SUPPRESS_GENERATION.
- super->constructor( previous = previous ).
-
- CLEAR me->textid.
- IF textid IS INITIAL.
- if_t100_message~t100key = if_t100_message=>default_textid.
- ELSE.
- if_t100_message~t100key = textid.
- ENDIF.
- ENDMETHOD.
-ENDCLASS.
-```
+[zcl_demo_abap_error_handling](./src/zcl_demo_abap_error_handling.clas.abap)
> **💡 Note**
-> Activate all classes.
-
-4. Create a message class
-
- - Right-click your package where you want to create the message class.
- - Choose *New -> Other ABAP Repository Object*.
- - Filter for *message class*.
- - Walk through the wizard. Provide the name `ZDEMO_ABAP_MESSAGES`.
- - When the message class screen is opened, add 5 messages and make the following entries:
- |Number|Short Text|
- |---|---|
- |001|An error occured (Nr. 001)|
- |002|Exception raised (Nr. 002)|
- |003|Test message (Nr. 003) &1 &2|
- |004|Message (Nr. 004) p1: "&1" p2: "&2" p3: "&3" p4: "&4"|
- |005|&1 &2 &3 &4|
-
- - Save. No activation required for this artifact.
-
-
-
\ No newline at end of file
+> - The example involves the following artifacts:
+> - One executable class `zcl_demo_abap_error_handling`
+> - Two self-defined example exception classes `zcx_demo_abap_error_a` and `zcx_demo_abap_error_b` (one implements the `IF_T100_DYN_MSG`, the other implements `IF_T100_MESSAGE`)
+> - One message class `zdemo_abap_messages` with 5 message texts that are used as exception texts
+> - The example explores syntax described and uses code snippets in the cheat sheet. It does not represent best practice implementations, and only focuses on demonstrating ABAP syntax.
+> - The executable example of the [Program Flow Logic](13_Program_Flow_Logic.md) cheat sheet also includes examples with error handling.
+> - The steps to import and run the code are outlined [here](README.md#-getting-started-with-the-examples).
+> - [Disclaimer](./README.md#%EF%B8%8F-disclaimer)
\ No newline at end of file
diff --git a/28_Regular_Expressions.md b/28_Regular_Expressions.md
index b89acc2..4e3d472 100644
--- a/28_Regular_Expressions.md
+++ b/28_Regular_Expressions.md
@@ -20,6 +20,7 @@
- [Built-In Functions in ABAP Using Regular Expressions](#built-in-functions-in-abap-using-regular-expressions)
- [Built-In Functions in ABAP SQL and CDS Using Regular Expressions](#built-in-functions-in-abap-sql-and-cds-using-regular-expressions)
- [System Classes for Regular Expressions: CL\_ABAP\_REGEX and CL\_ABAP\_MATCHER](#system-classes-for-regular-expressions-cl_abap_regex-and-cl_abap_matcher)
+ - [Executable Example](#executable-example)
## Introduction
@@ -1443,4 +1444,13 @@ DATA(repl_count_not_extended) = matcher_not_extended->replace_all( newtext = `#`
DATA(repl_result_not_extended) = matcher_not_extended->text.
```
-
⬆️ back to top
\ No newline at end of file
+⬆️ back to top
+
+## Executable Example
+
+[zcl_demo_abap_regex](./src/zcl_demo_abap_regex.clas.abap)
+
+> **💡 Note**
+> - The [executable example](./src/zcl_demo_abap_string_proc.clas.abap) of the [String Processing](07_String_Processing.md) cheat sheet also includes examples with regular expressions.
+> - The steps to import and run the code are outlined [here](README.md#-getting-started-with-the-examples).
+> - [Disclaimer](./README.md#%EF%B8%8F-disclaimer)
\ No newline at end of file