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: 
former_member763514
Active Participant
In an Introduction to Messages in ABAP blog post, I already explained the basics of messaging concepts. Here, I would like to continiue further with the evolution of messaging in ABAP to the new form. From release 7.52, short new form USING MESSAGE of statement RAISE EXCEPTION with the addition MESSAGE makes it possible to pass the content of system fields implicitly to the exceptions of exception classes that include the system interface IF_T100_DYN_MSG.

To start with, let me give you a quick recap on what the exceptions are and the way we can handle them.

Recap


Messages are texts that are created using a message maintenance (transaction SE91). They are stored in the system table T100.It was demanded to associate objects with messages and display them using the statement MESSAGE. This was intended mainly for exception texts of exception classes.

Exceptions are events during the execution of an ABAP program that interrupt the program flow because it is not possible for the program to continue in a meaningful way. These events are either catchable or uncatchable. Uncatchable exceptions are raised only by the ABAP runtime framework and produce a runtime error, which I already discussed it in another blog post. Catchable exceptions are class-based and can be handled between TRY and ENDTRY control structure. The TRY block defines a protected area whose exceptions can be handled in subsequent CATCH blocks. A CATCH block handles the exceptions of the exception classes cx_class1 cx_class2 ... that are specified after the statement CATCH, as well as the exceptions of the subclasses of these exception classes.

Exception classes are either predefined globally in the system or can be defined by the user both globally and locally. There are two options for raising class-based exceptions.

  • System-driven raising in the runtime environment

  • Program-driven raising in the ABAP program


The associated exception classes which are predefined in the system, begin with the prefix CX_SY_, such as CX_SY_ZERODIVIDE. In the ABAP keyword documentation, the exception classes whose exceptions may occur when a corresponding ABAP statement is executed are listed for each keyword.

Before exception classes were introduced, one could handle the error message in a function module as an exception with text via the general exception ‘error_message’. Such non-class-based exceptions can also be handled in function modules as well as class definitions by defining an exception and ‘raising’ it.

Later, it was demanded to associate objects with messages and display them using the statement MESSAGE. This was intended mainly for exception texts of exception classes. As the exception class concept is defined, the main question was, how one can connect the messages to the classes. That was the reason for the emergence of system interfaces IF_T100_MESSAGE and IF_T100_DYN_MSG which can be linked to classes to make classes as carriers of messages. However, this causes complexity due to a double indirection.

IF_T100_MESSAGE and IF_T100_DYN_MSG objects, and in particular exception objects, can also become carriers of any message. This allows “old” exceptions to be turned into new ones. The entire syntax is then only used to get the contents of the system fields that were filled with MESSAGE into the attributes of the classes. In the following, I try to explain it all in more details. So, if you are also curious to know how messaging evolved in ABAP, please accompany me.

Non-Class-Based Exception Handling


Before the class-based messages were invented, one way of handling the messages was using the function module:
FUNCTION ZMSG_FUNC.
IF p IS INITIAL.
MESSAGE e000(ZCL_MSG_DEMO).
ENDIF.
ENDFUNCTION.

Then call the function in the program
REPORT zblog.
PARAMETERS p.

AT SELECTION-SCREEN.
CALL FUNCTION 'ZMSG_FUNC' EXPORTING p = p.

As before, the error message will raise by the function module until the user give a value to the variable. The point is that the function module is reusable in different situations.  Besides, by means of the function modules, we can handle the exception using ‘error-message’ concept. For example
  CALL FUNCTION 'ZMSG_FUNC' 
EXPORTING p = p
EXCEPTIONS ERROR_MESSAGE = 404.

Here, the error-message converts the e-message sent by the function module into an exception form in a way that if P is empty, then the given number ‘404’ will be shown on the screen. So, it is how it was done in earlier time to use message instruction to send exception by using the special exception ‘error-message’. Conversely, if the exception is not handled then the message is sent.

One can also define an exception in a function module and use it by the add on ‘raising ‘. Hence, the message statement will be converted to a raise statement. The statement MESSAGE ... RAISING is primarily a statement for raising a non-class-based exceptions and not for sending messages. It only sends a message if the exception is not handled.


It is the other way to create exception texts and avoid the termination of the program.
FUNCTION ZMSG_FUNC.  
IF p IS INITIAL.
MESSAGE e000(ZCL_MSG_DEMO) RAISING msg_exc.
ENDIF.
ENDFUNCTION.

In the main program
  CALL FUNCTION 'ZMSG_FUNC'
EXPORTING p = p
EXCEPTIONS msg_exc = 404.

Like before, if the exception isn’t handled properly, the program will be terminated. If no return code is assigned to the exception, the addition RAISING is ignored and the message is sent using the statement MESSAGE and processed in accordance with its message type.

While ‘error-message’ is not supported by class definition, the latter can also be done using object-oriented concept.
CLASS zcl_msg DEFINITION .
PUBLIC SECTION.

CLASS-METHODS raise_excp EXCEPTIONS msg_exc.
ENDCLASS.

CLASS zcl_msg IMPLEMENTATION.

METHOD raise_excp.
MESSAGE e000(zcl_msg_demo) RAISING msg_exc.
ENDMETHOD.

ENDCLASS.

START-OF-SELECTION.

zcl_msg=>raise_excp( ).

By running the program, the message will be shown as expected:


Keep in mind that this addition only makes sense during the processing of methods and function modules in which the non-class-based exception is defined.

That was the world before the definition of class-based exception. The aim of the exception’s class definition was to have classes and objects as carriers of messages, the purpose of which is to make the entire exception texts in the exception classes. That was technically possible by defining the system interfaces IF_T100_MESSAGE and IF_T100_DYN_MSG which make it possible to associate objects with messages and display them using the statement MESSAGE. This is intended mainly for exception texts of exception classes.

In such cases, one way to define a message is using syntax

MESSAGE { oref [TYPE mtype] }

For oref, an object reference variable can be specified when the statement MESSAGE is executed, which points to an object whose class implements the system interface IF_T100_MESSAGE. The message type is either specified explicitly using TYPE mtype or determined implicitly. This means, if the object reference variable oref points to an object that includes the system interface IF_T100_DYN_MSG, the addition TYPE can be omitted and the message type from the interface attribute MSGTY of the object is used implicitly. oref is a functional operand position. If oref is specified, the addition WITH and the variant with INTO are not allowed.

Until release 7.54, the statement MESSAGE oref could only have the further additions RAISING and DISPLAY LIKE if TYPE was specified explicitly. These additions are now also possible if TYPE is not specified. A detailed example can be found in ABAP Keyword Documentation.

System Interfaces for Messages


The system interfaces for messages (IF_T100_MESSAGE and IF_T100_DYN_MSG) are designed mainly for exception texts and exception classes for messages.

The interface IF_T100_ MESSAGE contains a structured attribute T100KEY with the components MSGID and MSGNO referring to the message class and number. Though, it does not have any attributes for the message type. The interface IF_T100_DYN_MSG adds predefined attributes for the message type and the placeholders of the message to the interface IF_T100_MESSAGE.

The properties of the message specified after MESSAGE are assigned automatically to the associated attributes in exception classes that include IF_T100_DYN_MSG. This means if IF_T100_DYN_MSG is used, it is no longer necessary to create separate attributes for the placeholders of the message. The attributes of the interface are used instead. Furthermore, a message type can be stored and evaluated in the interface attribute msgty. Besides, IF_T100_MESSAGE is designed for static exception texts of exception classes, but IF_T100_DYN_MSG can associate any messages with exception classes.

The interface IF_T100_DYN_MSG is designed specifically for raising class-based exceptions with the addition MESSAGE of the statement RAISE EXCEPTION or the addition THROW in conditional expressions.

Class-Based Exceptions Using the Statement "RAISE EXCEPTION".


With error situations in the ABAP program, exceptions can be raised in a program-driven manner using the RAISE EXCEPTION statement or the addition THROW in conditional expressions. The general syntax form is

RAISE EXCEPTION  { {TYPE cx_class [message] [EXPORTING p1 = a1 p2 = a2 ...]}

  • If the addition TYPE is specified, an exception of exception class cx_class is raised and, if necessary, an exception object is created. Every exception class cx_class visible at this point can be specified after TYPE.

  • The addition message can be used to link the exception object to a message.

  • The addition EXPORTING can be used to assign actual parameters to the input parameters of the instance constructor of the exception class.


The addition MESSAGE passes the specification of a message to the exception object and can be written either in a long form (example below) or in the newly defined short form, USING MESSAGE (from release 7.52). This variant is a short form of the preceding variant of the MESSAGE addition with syntax:
... MESSAGE ID          sy-msgid
TYPE sy-msgty
NUMBER sy-msgno
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4 ...

The addition USING MESSAGE implicitly passes the specification of the message that is stored during the execution of the statement in the system fields sy-msgid, sy-msgty sy-msgno, and sy-msgv1 to sy-msgv4 to the exception class. This short form is particularly suitable for converting classic exceptions that were raised in function modules or methods with the statement MESSAGE RAISING, or messages that were caught with error_message, into class-based exceptions.

The full functionality of the addition MESSAGE is available only if the system interface IF_T100_DYN_MSG is implemented in the used exception class. This enables determining the message from the current content of the system fields sy-msg.

Example I


Raising of the exception CX_DEMO_DYN_T100 that implements the interface IF_T100_DYN_MSG. The addition MESSAGE is used to pass the properties of a message that determines the exception text. The attributes MSGV1 to MSGV4 of the interface IF_T100_DYN_MSG are assigned the texts specified using WITH.
CALL FUNCTION 'DEMO_FUNCTION_MESSAGE'
EXPORTING
message_type = 'A'
message_place = 'in Function Module'
message_event = 'START-OF-SELECTION'
EXCEPTIONS
error_message = 4.
"Long form
TRY.
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 .
CATCH cx_demo_dyn_t100 INTO DATA(oref).
cl_demo_output=>display( oref->get_text( ) &&
`, ` && oref->msgty ).
ENDTRY.

we can rewrite the try block of the above example in the following short form:

Example II


The example demonstrates the short form of the statement RAISE EXCEPTION with the addition USING MESSAGE.
"Short form
TRY.
RAISE EXCEPTION TYPE cx_demo_dyn_t100 USING MESSAGE.
CATCH cx_demo_dyn_t100 INTO DATA(oref).
cl_demo_output=>display( oref->get_text( ) &&
`, ` && oref->msgty ).ENDTRY.

Here, the addition USING MESSAGE is used, which explicitly passes the system fields sy-msgty, sy-msgid, sy-msgno, and sy-msgv1 to sy-msgv4 to the corresponding additions of the statement RAISE EXCEPTION. The example has the same functionality as the executable example introduced in the long form.

If you need more details regarding the topics, please check the hyperlinks provided for you in the text, also take a look at ABAP Keyword Documentation.
3 Comments
Jan-WillemK
Active Participant
0 Kudos

Hi safa_bahoosh

Nice blog, and good to get a refresher of how to use messages and exceptions.
Could you do me a favor, and check your links to SAP documentation? In the current form quite some links refer to pages starting with "ldai1uia.wdf.sap.corp:44300", and those are not freely available to the outside world.

Keep up the nice blogs!

regards - Jan-Willem

former_member763514
Active Participant
0 Kudos
Hello Jan

Thanks for the point and sorry for the inconvenience, the links are updated.

Regards

Safa
stephenl1
Participant
0 Kudos
Thanks for this.  One useful thing I've found is the ability to pass a message from one message class to another using RAISE EXCEPTION NEW and populating the PREVIOUS parameter

i.e.

      CATCH zcx_message_class_A INTO DATA(lx_exceptions).

RAISE EXCEPTION NEW zcx_message_class_Bprevious lx_exceptions
messages lx_exceptions->messages ).

 

The problem I've found with this is that the value held in IF_T100_DYN_MSG~MSGTY is lost during this passing of the values to the new exception class.

Wondering if you have discovered this issue and what can be done to fix it?

Thanks

Stephen
Labels in this area