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.
Showing results for 
Search instead for 
Did you mean: 
Active Contributor

I would like to share my approach of using exception classes and transport t100 messages inside of them. For one single message, there is nothing to talk about, you simply include the t100 interface and pass the message to the exception class. But what if you would like to pass a list of messages to the caller?

Using an application log (BAL)

In the past, I often proceeded like this: I created an object that manages the message list (the BAL_ functions). The SAP class CL_RECA_MESSAGE_LIST is great in doing this job. Then, I passed this object to the classes I invoke so these classes can collect messages there. In case of an error, I just had to use the message list to show a popup with all the messages.

The problem here is, that each caller of the class must provide a log object and all classes involved must have this global object for logging. That's not a really big thing, but I wasn't satisfied with the solution. So I came to a new approach, which is including the log in the exception class and passing it in this way.

The logged exception class

To try it yourself, you first need an exception class that contains a log object (based on CL_RECA_MESSAGE_LIST). Let's go:

Add the attribute for the log. The referenced type is IF_RECA_MESSAGE_LIST

And create a getter method for the log:

Activate the class.

Demo Application

The demo application has a controller and a model class. On running, the controller instantiates the model and calls the read method. Here an error is provocated and the message is being captured in the log. Then the log is passed to the exception object.

The main controller catches the exception and uses the log object to display the error in a popup.

Here is the code:

report zp_tool_test_logged_exc.

class lcl_controller definition.

   public section.
     methods run.

   private section.
     methods error
       importing io_log type ref to if_reca_message_list.


class lcl_model definition.

   public section.
     methods read raising zcx_tool_logged.



   new lcl_controller( )->run( ).

class lcl_controller implementation.

   method run.
     " create model.
     data(lo_model) = new lcl_model( ).

         lo_model->read( ).
       catch zcx_tool_logged into data(lo_err).
         " call error handling (which shows the log)
         error( lo_err->get_log( ) ).
         " show the log

   method error.

     call function 'RECA_GUI_MSGLIST_POPUP'
         io_msglist                   = io_log

     io_log->clear( ).

class lcl_model implementation.

   method read.
     data lo_messages type ref to if_reca_message_list.

     lo_messages = cf_reca_message_list=>create( ).

     " provocate an error

     message e000(0k) with 'Some application error' into sy-msgli.
     lo_messages->add_symsg( ).
     raise exception type zcx_tool_logged exporting mo_log = lo_messages.



Some notes

The log is kept local in the model here. If your model is more complex. it might be that you collect messages in various methods. In this case, it could make sense to create a class-global log. Make sure to clear the log after having displayed the message, so no previous messages will show up (see io_log->clear( )  in method error).

As you see in read the message is created with a standard MESSAGE statement, which captures the text in a dummy variable. This makes it simple to code the message and it will also update the where-used list of the message id in your system. I find this very useful. After the MESSAGE statement, a simple call of lo_messages->add_symsg( ) puts the values of SY-MSGNO, SY-MSGID and so on into the log. Afterwards the exception is raised passing the log into the exeption object.

If you do not know yet CL_RECA_MESSAGE_LIST, it's worth a look. It's full of useful methods!

Labels in this area