OData ABAP Backend Exceptions
State-of-the-Art SAPUI5 / Fiori Apps erfordern ein sauber implementiertes Error Handling. In diesem Knowlegebase-Artikel zeigen Ihnen die Experten der CloudDNA GmbH wie im OData Kontext mit Exceptions umgegangen wird. Sind OData Services in einem SAP NetWeaver ABAP Stack implementiert, gibt es zwei ABAP Klassen die für Exceptions verwendet werden:
- /IWBEP/CX_MGW_BUSI_EXCEPTION für Business / Logische Fehler
- /IWBEP/CX_MGW_TECH_EXCEPTION für Technische Fehler
Fehler können auf verschieden Arten geworfen werden. Nachfolgend zeigen wir Ihnen unterschiedliche Optionen.
Ein Möglichkeit ist es, über den MessageContainer den Fehlertext direkt zurückzuliefern. Diese Methode hat den Nachteil, dass die Fehlertexte hartkodiert sind und somit eine Übersetzung in unterschiedliche Sprachen nicht möglich ist.
METHOD customerset_get_entity.
SELECT SINGLE * FROM zcustomer where ...
IF sy-subrc NE 0.
mo_context->get_message_container( )->add_message_text_only(
iv_msg_type = 'E'
iv_msg_text = |Der angeforderte Datensatz wurde nicht gefunden.| ).
RAISE EXCEPTION TYPE /iwbep/cx_mgw_busi_exception
EXPORTING
message_container = mo_context->get_message_container( ).
ENDIF.
ENDMETHOD.
Eine weitere Möglichkeit besteht in der Verwendung einer Nachrichtenklasse. Damit können alle bekannten ABAP Tools wie z.B. die SE91 verwendet werden.
METHOD customerset_get_entity.
SELECT SINGLE * FROM zcustomer where ...
IF sy-subrc <> 0.
mo_context->get_message_container( )->add_message( iv_msg_type = 'E'
iv_msg_id = 'SY'
iv_msg_number = '100'
iv_msg_text = |Der angeforderte Datensatz wurde nicht gefunden.| ).
RAISE EXCEPTION TYPE /iwbep/cx_mgw_busi_exception
EXPORTING
message_container = mo_context->get_message_container( ).
ENDIF.
ENDMETHOD.
Eine weitere Möglichkeit in Kombination mit dem Message Container bietet sich, wenn Fehler in Form eine BABIRET2 Struktur vorliegen.
METHOD xyz_get_entity.
DATA: lt_return TYPE bapirettab.
CALL FUNCTION 'BAPI_CALL_XYZ'
...
TABLES
return = lt_return.
IF lt_return IS NOT INITIAL.
mo_context->get_message_container( )->add_messages_from_bapi( it_bapi_messages = lt_return ).
RAISE EXCEPTION TYPE /iwbep/cx_mgw_busi_exception
EXPORTING
message_container = mo_context->get_message_container( ).
ENDIF.
ENDMETHOD.
Es gibt in diesem Szenario auch die Option die Leading Message zu bestimmen. In diesem Fall muss das Coding leicht abgeändert werden.
METHOD xyz_get_entity.
DATA: lt_return TYPE bapirettab.
CALL FUNCTION 'BAPI_CALL_XYZ'
...
TABLES
return = lt_return.
IF lt_return IS NOT INITIAL.
mo_context->get_message_container( )->add_messages_from_bapi( it_bapi_messages = lt_return
iv_determine_leading_msg = /iwbep/if_message_container=>gcs_leading_msg_search_option-first ).
RAISE EXCEPTION TYPE /iwbep/cx_mgw_busi_exception
EXPORTING
message_container = mo_context->get_message_container( ).
ENDIF.
ENDMETHOD.
Exceptions können auch direkt ohne Verwendung des Message Containers geworfen werden.
METHOD customerset_get_entity.
SELECT SINGLE * FROM zcustomer where ...
IF sy-subrc NE 0.
RAISE EXCEPTION TYPE /iwbep/cx_mgw_busi_exception
EXPORTING
textid = /iwbep/cx_mgw_busi_exception=>business_error
message = |Der angeforderte Datensatz wurde nicht gefunden.|.
ENDIF.
ENDMETHOD.
Eine weitere Option besteht darin, der Exception eine Struktur vom Typ scx_t100key mitzugeben.
METHOD customerset_get_entity.
SELECT SINGLE * FROM zcustomer where ...
IF sy-subrc NE 0.
DATA(lv_message) = VALUE scx_t100key( msgid = 'SY'
msgno = '001'
attr1 = |Der angeforderte Datensatz wurde nicht gefunden.| ).
RAISE EXCEPTION TYPE /iwbep/cx_mgw_busi_exception
EXPORTING
textid = lv_message.
ENDIF.
ENDMETHOD.
Die letzte in diesem Knowledgebase-Artikel dargestellte Option ist es, eine Exception abzufangen, und den Exceptiontext durchzureichen.
METHOD customerset_get_entity.
TRY.
...
CATCH cx_root INTO DATA(lr_ex).
RAISE EXCEPTION TYPE /iwbep/cx_mgw_busi_exception
EXPORTING
textid = /iwbep/cx_mgw_busi_exception=>business_error
message = |{ lr_ex->get_text( ) }|.
ENDTRY.
ENDMETHOD.