Application Development Blog Posts
Learn and share on deeper, cross technology development topics such as integration and connectivity, automation, cloud extensibility, developing at scale, and security.
cancel
Showing results for 
Search instead for 
Did you mean: 
horst_keller
Product and Topic Expert
Product and Topic Expert

Messages are basically short texts stored in database table T100. What makes them special is the ABAP statement MESSAGE. This statement sends a message with a short text from T100 and adds a message type (S, I, W, E, A, X). The system behavior after sending a message is extremely context dependent and I'm not really confident that the documentation covers all the possible situations.

Historically, messages were invented for the PAI-handling of classical dynpros. There they can be used to conduct an error dialog. As a rule, messages should be restricted to that usage. But there is an important exception. Messages are also closely connected to exception handling:

  • In exception classes that implement IF_T100_MESSAGE, messages from T100 can serve as exception texts. Then they are part of the semantical properties of an exception class besides the class name and its super classes.

  • For non-class-based exceptions, messages can play the role of a poor man's exception text concept.

    • By raising a classical exception with MESSAGE RASING instead of RAISE, you add the message text and type to the exception. After handling such a classical exception with the  EXCEPTIONS addition of the CALL statement, you find the information in the well known system fields sy-msg... .

    • You can catch messages sent with MESSAGE naming the predefined classical exception error_message behind EXCEPTIONS of the CALL statement.

What's missing?

Nowadays you work with class based exceptions in your application programs. But from time to time you have to call legacy procedures that throw classical exceptions that are bound to messages. If you cannot handle the reason of the exception in place, you want to pass it to your caller in form of a class based exception. The problem is, how to find an appropriate exception class and how to convert the message based exception text of the original exception to an exception text of the exception class?

Since the exception texts of an exception class are part of their semantics, you would need an own exception class or at least exception text for each message that might occurr. Then you can raise the class based exception e.g. as follows:

meth( EXCEPTIONS exception = 4 ).

IF sy-subrc = 4.

  RAISE EXCEPTION TYPE cx_demo_t100

    EXPORTING

      textid = cx_demo_t100=>demo

      text1  = CONV #( sy-msgv1 )

      text2  = CONV #( sy-msgv2 )

      text3  = CONV #( sy-msgv3 )

      text4  = CONV #( sy-msgv4 ).

ENDIF.

Here, meth is a method that raises a classical exception exception with MESSAGE RAISING and cx_demo_t100 implements IF_T100_MESSAGE and denotes a message that fits to the message passed by the classical exception. If there is no approptiate exception class at hand that is able to cover all the messages that might be send by a called procedure, shrewd developers proceed also as follows:

meth( EXCEPTIONS exception = 4 ).

IF sy-subrc = 4.

  RAISE EXCEPTION TYPE cx_demo_t100

    EXPORTING

      textid = VALUE scx_t100key( msgid = sy-msgid

                                  msgno = sy-msgno

                                  attr1 = 'TEXT1'

                                  attr2 = 'TEXT2'

                                  attr3 = 'TEXT3'

                                  attr4 = 'TEXT4' )

      text1  = CONV #( sy-msgv1 )

      text2  = CONV #( sy-msgv2 )

      text3  = CONV #( sy-msgv3 )

      text4  = CONV #( sy-msgv4 ).

ENDIF.

This exploits the fact, that you can pass any structure of type scx_t100key to the contructor of an exception class. By doing so, you define a message from T100 not statically as message text but when raising the exception. Only the attributes for the replacement texts have to be there. Knowing that, you can create a kind of generic exception class for messages. But this is not recommended for exception classes implementing IF_T100_MESSAGE. For such an exception class, the exception text should not be dynamic and you should pass constants of that class to the parameter textid only. Furthermore, the above coding is quiet cumbersome. And further-furthermore, there's no way to pass the message type.

Solution with ABAP 7.50

Since the above scenario is a valid use case, a solution is provided with ABAP 7.50: A new interface IF_T100_DYN_MSG that contains IF_T100_MESSAGE It adds an attribute msgty for the message type and it also adds predefined attributes msgv1 to msgv4 for the replacment texts (placeholders) of a message.

If an exception class cx_demo_dyn_t100 implements IF_T100_DYN_MSG, you can profit from a new MESSAGE addition to the RAISE EXCEPTION statement:

meth( EXCEPTIONS exception = 4 ).

IF sy-subrc = 4.

  RAISE EXCEPTION TYPE cx_demo_dyn_t100

    MESSAGE ID    sy-msgid

            TYPE   sy-msgty

            NUMBER sy-msgno

            WITH   sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.

ENDIF.

This does basically the same as the example above, but now in a well-educated way. You can pass the full signature of a message to an exception class including the message type and the runtime environment does the rest for you. Also, you don't have to care about the names of the attributes for the placeholders any more. When handling the exception you have access to the message, e.g. as follows:

CATCH cx_demo_dyn_t100 INTO DATA(oref).

  cl_demo_output=>display(

    |Caught exception:\n\n| &&

    |"{ oref->get_text( ) }" of type { oref->msgty }| ).

You get back the message text and, that's new, also the message type. From now on, this is the recommended way of converting classical messages to exceptions.

For more information and more examples see:

The MESSAGE addition is also available for THROW in conditional expressions, of course.

21 Comments