У меня есть несколько настраиваемых классов исключений, которые были созданы «С классом сообщений». Поскольку я не могу напрямую получить от них сообщение, я хочу создать служебный метод, который возвращает BAPIRET2 из заданного исключения на основе значений в IF_T100_MESSAGE~T100KEY. Однако я не могу предоставить этому методу общий параметр импорта CX_ROOT, поскольку этот класс не поддерживает сообщения. Я также не могу создать общий класс исключений с поддержкой сообщений, поскольку новые классы должны наследовать от одного из CX_STATIC_CHECK, CX_DYNAMIC_CHECK или CX_NOCHECK.

Как я могу получить сведения о сообщении из неопределенного исключения? Должен ли я создать метод, который получает CX_ROOT, а затем выполняет до трех вызовов методов с типом импорта для каждого из трех возможных подклассов? Или есть альтернативы получше?

2
Lilienthal 22 Апр 2014 в 12:24

4 ответа

Лучший ответ

Вы можете подготовить дескриптор типа интерфейса (один раз):

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.
2
vwegert 22 Апр 2014 в 09:15

Вы можете использовать объект сборщика сообщений, например

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
user3665988 22 Май 2014 в 16:30

Для класса ведения журнала я использую что-то вроде этого:

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.

Надеюсь, это поможет, поскольку я боролся с той же проблемой. Возможно, потребуется некоторая корректировка, но я думаю, что вы поняли основную идею. Этот метод может обрабатывать

1
stefango79 29 Июл 2014 в 13:17

Возможно, я что-то упускаю, но нельзя ли просто использовать IF_MESSAGE~GET_TEXT, который присутствует на CX_ROOT?

В противном случае я бы возложил на настраиваемый класс исключений ответственность за наличие метода, который может возвращать правильное сообщение (он может полагаться на служебный метод, который вы планируете).

0
tomdemuyt 23 Апр 2014 в 16:23