我有几个“使用Message Class”创建的自定义异常类。由于我无法直接从它们获取消息,因此我想创建一个实用程序方法,该方法根据BAPIRET2
中的值从给定的异常中返回IF_T100_MESSAGE~T100KEY
。但是,我无法使用通用CX_ROOT
导入参数提供该方法,因为此类未启用消息。我也无法创建通用的消息启用异常类,因为新类必须从CX_STATIC_CHECK
,CX_DYNAMIC_CHECK
或CX_NOCHECK
之一继承。
如何从未指定的异常中检索消息详细信息?我是否应该创建一个接收CX_ROOT
的方法,然后最多三次调用方法,并将导入类型分别输入到三个可能的子类中?或者有更好的选择吗?
答案 0 :(得分:2)
您可以准备一个接口的类型描述符(一次):
DATA: lr_t100_descr TYPE REF TO cl_abap_intfdescr.
lr_t100_descr ?= cl_abap_typedescr=>describe_by_name( 'IF_T100_MESSAGE' ).
然后按照自己的方式检查每个异常:
DATA: lr_t100_exception TYPE REF TO if_t100_message.
IF lr_t100_descr->applies_to( ir_any_exception ) = abap_true.
lr_t100_exception ?= ir_any_exception.
" ...
ENDIF.
答案 1 :(得分:1)
您可以使用消息收集器对象,例如
DATA:
excp type ref to CX_ROOT,
bapi_messages type BAPIRETTAB,
message_collector type ref to IF_RECA_MESSAGE_LIST.
FIELD_SYMBOLS:
<bapi_message> TYPE BAPIRET2.
message_collector = cf_reca_message_list=>create( ).
TRY.
" some code which may cause and exception
CATCH cx_root into excp.
message_collector->add_from_exxeption( io_exception = excp).
ENDTRY.
bapi_messages = message_collector->get_list_as_bapiret( ).
LOOP AT bapi_messages ASSIGNING <bapi_message>.
" write out message
ENDLOOP.
非常值得查看消息收集器对象。
答案 2 :(得分:1)
对于日志记录类,我使用以下内容:
METHOD add_message_exception.
DATA:
lr_type TYPE REF TO cl_abap_typedescr,
lr_class TYPE REF TO cl_abap_classdescr,
lr_intf TYPE REF TO cl_abap_intfdescr,
l_bapiret2 TYPE bapiret2,
lr_msg TYPE REF TO if_t100_message.
CHECK ir_exception IS NOT INITIAL.
l_bapiret2-type = i_type.
"Test for T100KEY interface
cl_abap_classdescr=>describe_by_object_ref(
EXPORTING
p_object_ref = ir_exception
RECEIVING
p_descr_ref = lr_type
EXCEPTIONS
reference_is_initial = 1
OTHERS = 2 ).
TRY.
lr_class ?= lr_type.
IF sy-subrc = 0.
lr_class->get_interface_type(
EXPORTING
p_name = 'IF_T100_MESSAGE'
RECEIVING
p_descr_ref = lr_intf
EXCEPTIONS
interface_not_found = 1
OTHERS = 2 ).
IF sy-subrc = 0.
lr_msg ?= ir_exception. "Cast to interface
l_bapiret2-id = lr_msg->t100key-msgid.
l_bapiret2-number = lr_msg->t100key-msgno.
cl_message_helper=>set_msg_vars_for_if_t100_msg( text = lr_msg ).
l_bapiret2-message_v1 = sy-msgv1.
l_bapiret2-message_v2 = sy-msgv2.
l_bapiret2-message_v3 = sy-msgv3.
l_bapiret2-message_v4 = sy-msgv4.
l_bapiret2-message = me->get_msg(
i_msgid = l_bapiret2-id
i_msgno = l_bapiret2-number ).
ENDIF.
ENDIF.
CATCH cx_root.
"Pokémon exception handling
ENDTRY.
"No T100KEY Interface available
IF lr_msg IS INITIAL.
l_bapiret2-message = ir_exception->if_message~get_text( ).
l_bapiret2-message_v1 = sy-msgv1.
l_bapiret2-message_v2 = sy-msgv2.
l_bapiret2-message_v3 = sy-msgv3.
l_bapiret2-message_v4 = sy-msgv4.
ENDIF.
ENDMETHOD.
希望这有助于解决同样的问题。也许需要一些调整,但我认为你得到了基本的想法。这个方法可以处理
答案 3 :(得分:0)
我可能会遗漏某些内容,但您不能只使用IF_MESSAGE~GET_TEXT
上的CX_ROOT
吗?
否则,我会让自定义异常类负责拥有一个可以返回正确消息的方法(它可能依赖于您计划的实用方法)。