"
Apoiado por

Obtém o texto mais profundo de cadeia de excepções

Nos dias que correm se não estás a usar objectos és totó.

Se usas objectos, espero que estejas a seguir a boa práctica de usar classes de excepções.

E se usas classes de excepção é bom que entendas a melhor forma de as usar, particularmente as vantagens de as encadear.

Com tudo isto esclarecido, chegamos ao que nos traz aqui hoje. No artigo sobre cadeias de excepções mostrei como, para obter o texto da excepção mais profunda, a que foi inicialmente espoletada, se pode fazer um DO WHILE:


DATA: text TYPE string,
      o_exp TYPE REF TO cx_root.
(…)
CATCH cx_fruta INTO o_exp.
    WHILE o_exp->previous IS BOUND.
        o_exp = o_exp->previous.
    ENDWHILE.
    text = o_exp->get_text( ).
ENDTRY.

Mas num cenário em que tens uma aplicação com muitas excepções, todas derivadas da mesma, podes fazer algo mais interessante:

  1. Crias uma excepção raiz para a aplicação ZCX_FRUTA
  2. Todas as excepções da aplicação herdam dessa (ZCX_FRUTA_BANANA, ZCX_FRUTA_ANANAS, etc.)
  3. Na excepção raiz ZCX_FRUTA fazes override ao método GET_TEXT() e encapsulas lá a lógica para obter o texto da mais profunda

O código do ZCX_FRUTA->GET_TEXT() será algo tipo:


METHOD GET_TEXT.
  if me->previous is bound.
    result = me->previous->get_text( ).
  else.
    result = super->if_message~get_text( ).
  endif.
ENDMETHOD.

Também convém fazer o mesmo ao método GET_LONG_TEXT() se estiveres a pensar usá-lo.

E pronto, agora já não precisas de fazer o WHILE no código que trata as excepções. Elas próprias saberão tratar de si. Basta chamares o GET_TEXT() da excepção que receberes e terás sempre a certeza de que recebes o texto mais profundo, que deverá ser o que melhor descreve o erro que ocorreu. E o código até é mais bonito por ser recursivo.

Nota 1: isto só fará sentido num cenário em que não queres dar uso aos textos de cada elemento da cadeia de excepções, que diria ser o mais comum. No passado já precisei de todas, para fazer log delas.

Nota 2: Infelizmente esta técnica não é compatível com o comando MESSAGE o_exp TYPE ‘E’. Por alguma razão quando fazes isto obténs sempre o texto da excepção de topo. Pena.

Foto via JanDix via Visualhunt

O Abapinho saúda-vos.

6 comentários a “Obtém o texto mais profundo de cadeia de excepções”

  1. Erick Carvalho Diz:

    Excelente post!!!!

  2. Nuno Godinho Diz:

    Obrigado Erick! Gostando tanto de ler os teus posts é bom saber que também posso dar algo em troca! :)

  3. Sérgio Fraga Diz:

    Excelente ideia!

    Para o exemplo funcionar falta fazer o downcast quanto se assigna a o_exp->previous a o_exp no while, isto porque a previous é do tipo cx_root, e a o_exp é uma excepção mais especifica.

  4. Nuno Godinho Diz:

    Olá Sérgio, Tinha-me esquceido de declarar o O_EXP mas este também deverá ser CX_ROOT. Assim não é preciso downcast.

  5. Sérgio Fraga Diz:

    Olá Nuno,

    Eu como sou um afortunado, e tenho à minha disposição o Netweaver 7.4, posso fazer:

    (…)
    CATCH cx_fruta INTO DATA(o_exp).
    WHILE o_exp->previous IS BOUND.
    o_exp ?= o_exp->previous.
    ENDWHILE.
    DATA(text) = o_exp->get_text( ).
    ENDTRY.

    Portanto para o caso de quem programa com a versão mais recente do ABAP, utilizando inline declarations, o downcast é mesmo necessário :)

  6. Nuno Godinho Diz:

    Entendido :) obrigado sortudo :)

Deixe um comentário


Acerca do Abapinho
O Abapinho é suportado pelo WordPress
Artigos (RSS) e Comentários (RSS).