ABAP – Local Exception class using IF_T100_MESSAGE

SAPIn this article I’ll show how to implement local exception class which will use all the benefits of interface IF_T100_MESSAGE – it will simply use the message classes for generating exception messages.

Here comes local exception class definition which:

  • Implements interface IF_T100_MESSAGE
  • Aliases IF_T100_MESSAGE~T100KEY to local T100KEY
  • Defines 5 PUBLIC variables (MSGV1-4, WERKS) to be used in constructor to generate the message. Generally there can be any number and any type of variable – it allows type checking!!!)
  • Defines your messages as class public constants (GENERAL_ERROR_4VARS, WRONG_PLANT), where the message class, message number and substitution variables (ATTR1-4) are assigned with name of the class PUBLIC variables (MSGV1-4, WERKS) – their contents will be used to substitute the ‘&’ in the message
CLASS lcx_exception DEFINITION
  INHERITING FROM cx_static_check.
  PUBLIC SECTION.
    INTERFACES if_t100_message .

    ALIASES t100key
      FOR if_t100_message~t100key .

    DATA:
      msgv1 TYPE msgv1,
      msgv2 TYPE msgv2,
      msgv3 TYPE msgv3,
      msgv4 TYPE msgv4,
      werks TYPE werks_d.

    METHODS: constructor
      IMPORTING
        textid   LIKE if_t100_message=>t100key OPTIONAL
        previous LIKE previous OPTIONAL
        t100key  TYPE scx_t100key OPTIONAL 
        msgv1    TYPE msgv1 OPTIONAL
        msgv2    TYPE msgv2 OPTIONAL
        msgv3    TYPE msgv3 OPTIONAL
        msgv4    TYPE msgv4 OPTIONAL
        werks    TYPE werks_d OPTIONAL.

    CONSTANTS:
      BEGIN OF GENERAL_ERROR_4VARS,
        msgid TYPE symsgid VALUE 'ZX01',        " Message class(SE91)
        msgno TYPE symsgno VALUE '000',
        attr1 TYPE scx_attrname VALUE 'MSGV1',
        attr2 TYPE scx_attrname VALUE 'MSGV2',
        attr3 TYPE scx_attrname VALUE 'MSGV3',
        attr4 TYPE scx_attrname VALUE 'MSGV4',
      END OF GENERAL_ERROR_4VARS,

      BEGIN OF WRONG_PLANT,
        msgid TYPE symsgid VALUE 'ZX01',
        msgno TYPE symsgno VALUE '001',
        attr1 TYPE scx_attrname VALUE 'WERKS',
        attr2 TYPE scx_attrname VALUE '',
        attr3 TYPE scx_attrname VALUE '',
        attr4 TYPE scx_attrname VALUE '',
      END OF WRONG_PLANT.
ENDCLASS.               "lcx_exception

The implementation of the exception class will now be simple as everything else is already defined in the standard super class cx_static_check.

CLASS lcx_exception IMPLEMENTATION.
  METHOD constructor.
    CALL METHOD super->constructor
      EXPORTING
        previous = previous.
    me->msgv1 = msgv1 .
    me->msgv2 = msgv2 .
    me->msgv3 = msgv3 .
    me->msgv4 = msgv4 .
    me->werks = werks .

    me->t100key = t100key .
    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.               "lcx_exception

Now let’s define our class which:

  • Will use the local exception class in the method’s RAISING part of definition
CLASS lcl_demo_class DEFINITION
  PUBLIC SECTION.
    DATA:
      mv_werks TYPE werks_d.

    METHODS:
      constructor IMPORTING iv_werks TYPE werks_d
                  RAISING lcx_exception,
      get_data
        RAISING lcx_exception.
ENDCLASS.

Implementation of the local class will be raising our exceptions…

CLASS lcl_demo_class IMPLEMENTATION.
  METHOD constructor.
    IF iv_werks <> '1234'.
      RAISE EXCEPTION TYPE lcx_exception
        EXPORTING
          textid = lcx_exception=>WRONG_PLANT
          werks  = iv_werks.
    ENDIF.
  ENDMETHOD.
 
  METHOD get_data.
*   If there is an error in your code -> raise exception
    IF 1 <> 2.
      RAISE EXCEPTION TYPE lcx_exception
        EXPORTING
          textid = lcx_exception=>GENERAL_ERROR_4VARS
          msgv1  = |Something happened in our very beautiful|
          msgv2  = |MEGA HYPER SUPER TROUPER plant:|
          msgv3  = |{ mv_werks }|.
    ENDIF.
  ENDMETHOD.
ENDCLASS.

Now let’s use the prepared classes in real code:

DATA:
  lo_demo_class TYPE REF TO lcl_demo_class,
  lo_exception  TYPE REF TO lcx_exception.

*************************************
* Demo with wrong plant
TRY.
    CREATE OBJECT lo_demo_class
      EXPORTING 
        iv_werks = '2345'.
  CATCH lcx_exception INTO lo_exception.
    MESSAGE lo_exception->get_text( ) TYPE 'S' DISPLAY LIKE 'E'.
ENDTRY.
*************************************
* Demo with correct plant which fails 
* however during GET_DATA method

* Note: Each TRY-CATCH-ENDTRY should always be separated to
* catch/isolate single possible exception -> 
* we have two blocks of TRY-CATCH-ENDTRY
TRY.
    CREATE OBJECT lo_demo_class
      EXPORTING 
        iv_werks = '1234'.
  CATCH lcx_exception INTO lo_exception.
    MESSAGE lo_exception->get_text( ) TYPE 'S' DISPLAY LIKE 'E'.
ENDTRY.
TRY.
    lo_demo_class->get_data( ).
  CATCH lcx_exception INTO lo_exception.
    MESSAGE lo_exception->get_text( ) TYPE 'S' DISPLAY LIKE 'E'.
ENDTRY.

Leave a Reply