Avoid messages in business logic - SchwarzIT/sap-usi-logging-api Wiki
Messages should only be sent by the main method that controls the processing.
If your code is throwing messages all over the place, you will run into issues using the logging API.
METHOD handle_use_case. DATA(logger) = /usi/cl_bal_factory=>get_instance( )->create_new_logger( i_log_object = 'ZMY_REPORT' i_sub_object = 'DO_SOMETHING' i_external_id = i_input ). DATA(token) = logger->claim_ownership( ). some_bad_method( i_input ). logger->save( token ). logger->free( token ). ENDMETHOD. METHOD some_bad_method. IF i_input IS INITIAL. MESSAGE e000(38) WITH 'This message will break the log!'. " <----- BAD! DON'T DO THIS! ENDIF. [...] ENDMETHOD.
As the message statement would stop PAI-processing, method handle_use_case( ) would not reach its regular end and the log would not be saved.
This would leave you with "some random error" message, but without a log.
HINT: If you should ever screw this up, check the auto-save-feature. It could be very helpful in tracking down the responsible code location. There are two ways to activate the feature:
- Permanently: Customizing -> Log Levels -> Product specific Log Level
- Temporarily: Customizing -> Log Levels -> User specific Log Level
HINT 2: If you have to call legacy code or external APIs, that might send messages, you could encapsulate the call in a function module. If said function module has an exception 'ERROR_MESSAGE' will result in SY-SUBRC being <> 0. You can obtain the message text from the SY-MSG*-Fields in that case.
A better way
The following code avoids this issue by using object oriented exceptions.
METHOD handle_use_case. DATA(logger) = /usi/cl_bal_factory=>get_instance( )->create_new_logger( i_log_object = 'ZMY_REPORT' i_sub_object = 'DO_SOMETHING' i_external_id = i_input ). DATA(token) = logger->claim_ownership( ). TRY. some_better_method( i_input ). CATCH zcx_my_exception INTO DATA(the_exception). logger->save( token ). logger->free( token ). MESSAGE the_exception TYPE 'E'. ENDTRY. logger->save( token ). logger->free( token ). ENDMETHOD. METHOD some_better_method. IF i_input IS INITIAL. TRY. RAISE EXCEPTION TYPE zcx_my_exception EXPORTING textid = VALUE #( msgid = '38' msgno = 000 attr1 = 'PARAM1' ) param1 = 'NOPE!'. CLEANUP INTO DATA(exception). usi/cl_bal_factory=>get_instance( )->get_existing_logger( )->add_exception( exception ). ENDTRY. ENDIF. [...] ENDMETHOD.
Method handle_use_case( ) is the one and only method that is allowed to use messages.
All methods, that are called by handle_use_case( ) are using object oriented exceptions instead.
This will ensure, that the regular end of method handle_use_case( ) will be reached, which gives it a fair chance to save the log.