Skip to Content
Author's profile photo Jerry Wang

How to persist the UI exception so you can view them later

When I am working together with local partner to resolve one issue caused by incorrect enhancement set configuration for new custom Product set type, I have realized that if the UI exception is raised and caught by framework, there would be no entry in ST22, which causes the difficulties for later trouble shooting.

When I am debugging the code how the framework handles with the exception, I found there is the possibility to let the framework call the error handler defined by ourselves being registered in table bsperrhandler.

/wp-content/uploads/2013/12/clipboard1_348639.png

So I think it is worthy to create a simple error handler class to persist the exception information into a new transparent table for later checking.

1. create a class ZCL_ERROR_HANDLER with a static public method STORE_ERROR_INFO, signature as below:

/wp-content/uploads/2013/12/clipboard2_348644.png

Source code as below. Just extract error message text and the exact position which line of source code has raised the exception:

METHOD store_error_info.
  DATA: lv_header_text TYPE string,
        l_einternal TYPE REF TO cx_bsp_einternal,
        l_exception      TYPE REF TO cx_root,
        l_program_name   TYPE syrepid,
        l_include_name   TYPE syrepid,
        l_source_line    TYPE i,
        lv_log_text      TYPE string,
        ls_log           TYPE zbsplog.
  l_exception = exception.
  CHECK server IS NOT INITIAL AND exception IS NOT INITIAL.
  lv_header_text = exception->get_text( ).
  TRY.
      l_einternal ?= exception.
    CATCH cx_root.
  ENDTRY.
  IF l_einternal IS BOUND.
    CALL METHOD l_einternal->get_source_position
      IMPORTING
        program_name = l_program_name
        include_name = l_include_name
        source_line  = l_source_line.
  ELSE.
    WHILE l_exception->previous IS BOUND.
      l_exception = l_exception->previous.
    ENDWHILE.
    CALL METHOD l_exception->get_source_position
      IMPORTING
        program_name = l_program_name
        include_name = l_include_name
        source_line  = l_source_line.
  ENDIF.
  CALL FUNCTION 'GUID_CREATE'
    IMPORTING
      ev_guid_16 = ls_log-uuid.
  ls_log-error_date = sy-datlo.
  ls_log-error_time = sy-timlo.
  ls_log-error_string = |<head><h1>{ lv_header_text }</h1><h2>Error Date:{ sy-datlo }</h2><h2>Error Time:{ sy-timlo }</h2>| &&
  |<h3>Error program:{ l_program_name }</h3><h3>Error include:{ l_include_name }</h3><h3>Source code line number:{ l_source_line }</h3>|
  && |</head>|.
  INSERT zbsplog FROM ls_log.
  COMMIT WORK AND WAIT.
ENDMETHOD.

2. Create a new transparent table to store the exception detail:

/wp-content/uploads/2013/12/clipboard3_348645.png

3. Register the new error handler into table bsperrhandler:

/wp-content/uploads/2013/12/clipboard4_348646.png

4. Write a simple report to list the exception information. Of course more elegant UI like ALV could be used:

data: lt_table type STANDARD TABLE OF zbsplog,
      lv_error TYPE zbsplog-error_string.
FIELD-SYMBOLS:<item> TYPE zbsplog.
START-OF-SELECTION.
   SELECT * INTO TABLE lt_table FROM zbsplog.
   LOOP AT lt_table ASSIGNING <item>.
      WRITE:/ 'guid: ', <item>-uuid,'date: ', <item>-error_date, <item>-error_time.
      lv_error = <item>-error_string.
      HIDE lv_error.
   ENDLOOP.
   AT LINE-SELECTION.
      cl_demo_output=>display_html( lv_error ).

execute the report and double click one line item, the detail information would be displayed via the handy class cl_demo_output.

With the include name and source code line number available, you could implement further handling like automatically navigation to the source code in ABAP editor by calling function module RS_TOOL_ACCESS with include name and source code number passed in.

/wp-content/uploads/2013/12/clipboard5_348647.png

Assigned Tags

      3 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Former Member
      Former Member

      Very Very useful!! 😎

      Author's profile photo praveen kumar mannala
      praveen kumar mannala

       

      Hi Jerry. thanks a lot. just one question, can we use this method to get full call stack. we are getting cx_bol_exception lot of times. UI is showing the exception in 259 line of reread entity method. however, we are not able to reproduce these kind of errors in quality. we know exact place however we want to know what is the complete call stack. Is it possible get that ? Kindly let me know.

      Author's profile photo Jerry Wang
      Jerry Wang
      Blog Post Author

      Hello,

      Then you could try to call function module SYSTEM_CALLSTACK to get callstack and store this information into your persistent table.

      Best regards,

      Jerry