
ABAP Quick - Handling of Function modules
How do you actually handle function modules and error handling within ABAP? In this short tip, we'll also look at handling them within the context of RFC.
Table of contents
In this article, we'll discuss error handling in classic function modules. With ABAP Cloud, you generally need fewer and fewer modules, as many functions are wrapped in classes.
Introduction
Handling function modules, especially as BAPIs, will remain with us for a few more years. However, as developers, we should also be able to handle the various processing states. Therefore, we need to know how errors are generated in function modules, what information we receive, and how to handle RFC function modules cleanly. You can find the general documentation used below in the sources.
Since this is primarily about error handling and message processing, we will use the ABAP Message Logger to process the messages and errors.
Error Handling
Let's look at various function modules and scenarios. The function module is imaginary and we are using it only for illustration.
None
In this very simple scenario, we do not receive an exception from the function module. We input information and receive a structure with information. Here, we mainly work with the return from the function module. Generally, you should check the function module's signature to see if it contains any exceptions.
CALL FUNCTION 'Z_BS_DEMO_INFORMATIONS'
EXPORTING
id_char = character
id_number = number
IMPORTING
es_info = returned_information.
Exceptions
In the next example, we define EXCEPTIONS. These are not exceptions from object-oriented development, but classic exceptions. After the keyword, you will find some defined exceptions, such as NOT_FOUND and the assignment to a SUBRC. In principle, not all exceptions need to be caught and assigned; you can also assign the rest under OTHERS. This is a generic exception that handles everything. This is especially helpful if the function module's exceptions are expanded later.
CALL FUNCTION 'Z_BS_DEMO_INFORMATIONS'
EXPORTING
id_char = character
id_number = number
IMPORTING
es_info = returned_information
EXCEPTIONS
not_found = 1
OTHERS = 2.
If the exception is triggered, the SY-SUBRC is set to the defined value. You should then react to it after the function module. Error messages are usually written to the system fields. In this case, we can retrieve and save the system fields using the Log object.
IF sy-subrc <> 0.
log->add_message_system( ).
ENDIF.
Depending on the error, you should also change the further processing, i.e., either react to it, abort, or invalidate the data record. Often, you see in coding that the program continues after an erroneous call without even logging the error.
Return
When using BAPIs and other function modules, a RETURN parameter of type BAPIRET2 is usually used. This is a standardized type with information about notifications and messages.
CALL FUNCTION 'Z_BS_DEMO_INFORMATIONS'
EXPORTING
id_char = character
id_number = number
IMPORTING
es_info = returned_information
return = return.
Handling messages is often somewhat complicated, as either the entire table is checked, and then an error message is usually generated. We can save all messages directly via the log. Using helper methods, such as HAS_ERROR, we can then check whether there were any processing errors.
log->add_message_bapis( return ).
RFC Function Module
Now that you know the basics of normal function modules, let's take a look at processing with RFC (Remote Function Call) function modules. Here, we use a function module and add the DESTINATION keyword to call the function module on another system via a connection.
CALL FUNCTION 'Z_BS_DEMO_INFORMATIONS' DESTINATION destination
EXPORTING
id_char = character
id_number = number
IMPORTING
es_info = returned_information.
However, error handling is now missing here. Additional error sources arise with RFC calls, for example, the target system may not be accessible, the user may be locked, or permissions may be missing. Therefore, system exceptions must now be defined that do not exist in the actual function module. We write the messages to a separate variable.
DATA rfc_message TYPE c LENGTH 255.
CALL FUNCTION 'Z_BS_DEMO_INFORMATIONS' DESTINATION destination
EXPORTING
id_char = character
id_number = number
IMPORTING
es_info = returned_information
EXCEPTIONS
communication_failure = 1 MESSAGE rfc_message
system_failure = 2 MESSAGE rfc_message
OTHERS = 3.
You'll usually also find important information about the reason for the error in the message. Therefore, you should add a message about the abort to your log and then the message from the processing. In this case, the processing of the messages might look like this.
IF sy-subrc = 1.
log->add_message( class = 'Z_AML'
type = 'E'
number = '001' ).
log->add_message_text( rfc_message ).
ELSEIF sy-subrc = 2.
log->add_message( class = 'Z_AML'
type = 'E'
number = '002' ).
log->add_message_text( rfc_message ).
ELSE.
log->add_message( class = 'Z_AML'
type = 'E'
number = '003' ).
ENDIF.
Complete example
Here is the complete example from the article again. Since the function module is most likely not on your system, you can recreate the calls using other modules.
CLASS zcl_bs_demo_function_calls DEFINITION
PUBLIC FINAL
CREATE PUBLIC.
PUBLIC SECTION.
INTERFACES if_oo_adt_classrun.
PRIVATE SECTION.
DATA character TYPE c LENGTH 10.
DATA number TYPE i.
DATA returned_information TYPE string.
DATA log TYPE REF TO zif_aml_log.
METHODS handle_no_error.
METHODS handle_standard_error.
METHODS handle_bapi_return.
METHODS handle_rfc_call.
ENDCLASS.
CLASS zcl_bs_demo_function_calls IMPLEMENTATION.
METHOD if_oo_adt_classrun~main.
log = zcl_aml_log_factory=>create( ).
handle_no_error( ).
handle_standard_error( ).
handle_bapi_return( ).
handle_rfc_call( ).
ENDMETHOD.
METHOD handle_no_error.
CALL FUNCTION 'Z_BS_DEMO_INFORMATIONS'
EXPORTING
id_char = character
id_number = number
IMPORTING
es_info = returned_information.
ENDMETHOD.
METHOD handle_standard_error.
CALL FUNCTION 'Z_BS_DEMO_INFORMATIONS'
EXPORTING
id_char = character
id_number = number
IMPORTING
es_info = returned_information
EXCEPTIONS
not_found = 1
OTHERS = 2.
IF sy-subrc <> 0.
log->add_message_system( ).
ENDIF.
ENDMETHOD.
METHOD handle_bapi_return.
DATA return TYPE STANDARD TABLE OF bapiret2 WITH EMPTY KEY.
CALL FUNCTION 'Z_BS_DEMO_INFORMATIONS'
EXPORTING
id_char = character
id_number = number
IMPORTING
es_info = returned_information
return = return.
log->add_message_bapis( return ).
ENDMETHOD.
METHOD handle_rfc_call.
DATA destination TYPE string.
DATA rfc_message TYPE c LENGTH 255.
CALL FUNCTION 'Z_BS_DEMO_INFORMATIONS' DESTINATION destination
EXPORTING
id_char = character
id_number = number
IMPORTING
es_info = returned_information
EXCEPTIONS
communication_failure = 1 MESSAGE rfc_message
system_failure = 2 MESSAGE rfc_message
OTHERS = 3.
IF sy-subrc = 1.
log->add_message( class = 'Z_AML'
type = 'E'
number = '001' ).
log->add_message_text( rfc_message ).
ELSEIF sy-subrc = 2.
log->add_message( class = 'Z_AML'
type = 'E'
number = '002' ).
log->add_message_text( rfc_message ).
ELSE.
log->add_message( class = 'Z_AML'
type = 'E'
number = '003' ).
ENDIF.
ENDMETHOD.
ENDCLASS.
Conclusion
Handling error messages in function modules will continue to play a role in modern development. Therefore, you should fully implement error handling here and leave no gaps in the source code or after calls. With RFC function modules, there are additional tasks that you should definitely not forget.
Source:
SAP Help - CALL FUNCTION (Parameter)
SAP Help - CALL FUNCTION (Exception Handling)