2014-04-22 29 views
2

我有幾個自定義的異常類,創建「與消息類」。由於我無法直接從它們獲取消息,因此我想創建一個實用程序方法,該方法根據IF_T100_MESSAGE~T100KEY中的值從給定的異常中返回BAPIRET2。但是,我無法使用通用的CX_ROOT導入參數提供該方法,因爲此類未啓用消息。我也不能創建一個通用消息啓用的異常類,因爲新類必須從CX_STATIC_CHECK,CX_DYNAMIC_CHECKCX_NOCHECK之一繼承。CX_ROOT與消息類

我該如何從未指定的異常中檢索消息詳細信息?我是否應該創建一個方法來接收CX_ROOT,然後對三個可能的子類中的每一個輸入類型的方法進行最多三次調用?還是有更好的選擇?

回答

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. 
+0

這似乎是我正在尋找。接受警告,我沒有在我的方案中測試它,因爲它的規格發生了變化。 – Lilienthal

0

我可能失去了一些東西,但能你是不是隻用IF_MESSAGE~GET_TEXT這是CX_ROOT?否則,我會讓自定義異常類的職責是讓一個可以返回正確消息的方法(它可能依賴於您計劃的實用程序方法)。

+0

我嘗試過這種方法,但是IIRC由該方法返回的文本甚至不匹配啓用消息的類中設置的T100消息。即使這樣做,它只會讓我獲得文本,而不是我需要的消息(類)ID和號碼。你確實提出了一個很好的觀點,即我認爲應該在異常類本身上定義實用方法。一種解決方案是使用該實用程序方法創建三種基本異常類型的消息啓用實現,並從這些類中派生我的自定義異常。 – Lilienthal

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. 

這是值得檢查消息收集對象。

例如 http://wiki.scn.sap.com/wiki/display/profile/2007/07/09/Message+Handling+-+Finding+the+Needle+in+the+Haystack

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. 

希望這有助於爲我同樣的問題掙扎。也許有一些調整需要,但我認爲你有基本的想法。這種方法可以處理