Technology Blogs by SAP
Learn how to extend and personalize SAP applications. Follow the SAP technology blog for insights into SAP BTP, ABAP, SAP Analytics Cloud, SAP HANA, and more.
cancel
Showing results for 
Search instead for 
Did you mean: 
JerryWang
Product and Topic Expert
Product and Topic Expert
3,161

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.



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:



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:



3. Register the new error handler into table bsperrhandler:



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.




3 Comments