Errores en SAP – DUMPs

Hoy vamos a hablar de eso que aparece en tu vida de vez en cuando, que tu no quieres que pase, pero que es inevitable, al principio te enfada y te genera frustración, pero luego comprendes que puede ayudarte conocer y saber lo que pasa para no cometer errores mayores. No, no vamos a hablar de diarrea, bueno, un poco sí. Hoy vamos a hablar de los DUMPs y errores en SAP.


DUMPs

Lo primero que tenemos es que definir qué es un DUMP en SAP. Los DUMPs son los registros que se generan cuando un programa ABAP se ejecuta y algo sale mal que no puede ser manejado por el programa. Es un punto de ruptura o fuga de un programa ABAP en SAP.

Normalmente se tratan de errores generados por código de cliente (Z), normalmente. Pueden generarse en código estándar también, pero esto supondría una corrección por parte de SAP y una actualización del sistema vía support packages o notas. Y todos sabemos que todos los sistemas SAP están siempre, siempre, siempre actualizados ¿no? (no).

Mi cara cuando llego a un proyecto y pregunto por el nivel de parches

Sea como fuere, cuando una parte del código genera un error no controlado, se interrumpe y muestra un DUMP. Y si el programa se está ejecutando en fondo, se interrumpe y genera el DUMP igualmente pero está vez no hay usuario para verlo en directo claro.


Transacción ST22

La herramienta con la que contamos para buscar, identificar y analizar DUMPs es la ST22. Cuando accedemos a la ST22 lo primero que veremos será una pantalla de búsqueda como esta:

Donde tenemos, como importante:

  • Botón de Hoy: Nos permite acceder a la lista de Dumps de hoy en el sistema donde estamos logados, sea cual sea el usuario que generó el error. A la derecha del botón nos dará un contador del total de registros que coinciden.
  • Botón de Ayer: Nos permite acceder a la lista de Dumps de ayer en el sistema donde estamos logados, sea cual sea el usuario que generó el error. A la derecha del botón nos dará un contador del total de registros que coinciden.
  • Bloque de Selección propia: Nos permite buscar DUMPs por otros criterios que los simples «Hoy» y «Ayer». Por defecto vendrá con el usuario y el día de hoy, pero se puede cambiar. En mi experiencia yo solo lo he usado para buscar por otras fechas que no sean «Hoy» y «Ayer». También para filtrar por un usuario concreto.

Una vez ejecutada cualquiera de las opciones veremos la lista de DUMPs que concuerde con los criterios de selección ejecutados.


Listado de DUMPs

Donde como datos interesantes tenemos:

  • Fecha y Hora: Cuando se produjo el DUMP.
  • Usuario: Usuario de ejecución del programa que generó el DUMP
  • Conservar: Este campo refleja si un DUMP concreto ha sido marcado para ser guardado y no ser borrado en el job diario de limpieza de histórico. Para marcar como guardado o liberado debemos marcar un DUMP y pulsar el icono del candado de arriba.
  • Error tiempo ejecución ABAP: Es el tipo de DUMP que se ha generado. Luego vemos los tipos más comunes y su significado.
  • Programa: Lugar del código que ha generado el DUMP.

Si hacemos doble click encima de cualquier linea o le damos al primer icono de la botonera veremos el detalle de ese DUMP.


Vista de detalle del DUMP

Donde veremos que tenemos mucha información. Vamos a intentar desgranarlo porque esto es la parte importante de este artículo. No voy a explicar cada uno de los apartados, porque algunos de ellos no sé interpretarlos ni nunca me han hecho falta. Vamos a hacerlo de forma práctica en base a mi experiencia. Por lo tanto a continuación desgranaremos aquellos que creo fundamentales para saber identificar el error que subyace del DUMP.


Cabecera del Dump

Donde te da los datos básicos de cabecera del DUMP. Donde los más importante son:

  • Err.tmpo.ejec: El tipo de DUMP que estamos viendo
  • Programa ABAP: El programa que generó el DUMP
  • Fecha y hora: El momento en el que se generó.,

Texto Breve

Nos da un resumen muy somero del error ocurrido. Arriba he puesto varios ejemplos de distintos tipos de DUMPs. Nos da cierta información que puede ser importante, como por ejemplo la excepción no controlada que genera el DUMP o el motivo básico del error.


¿Qué ha sucedido?

Es una explicación un poco más extensa, siendo también muy resumida. Puede darnos algo de información dependiendo del tipo de DUMP.


¿Qué puede hacer?

En general este bloque no suele dar información muy valiosa, en algunos casos, como en el DUMP RFC_NO_AUTHORITY de arriba nos da algo más de los permisos que faltan por otorgar.


Análisis de Errores

Empieza la fiesta, este bloque ya puede contener información muy valiosa del error que ha sucedido. Cada tipo de DUMP contará con una información explicativa que puede ayudarnos a saber qué ocurrió.


Notas para corregir errores

Este bloque nos ayuda a buscar notas en el SAP Support Portal o para abrir una incidencia a SAP.


Info posición de cancelación

Este apartado nos da la posición del código donde se ha producido el error. Siendo importante esta información, en el siguiente punto tenemos la misma información pero con más funcionalidad,.


Detalle código fuente (Texto fuente modificado)

Ojo, que estamos en uno de los apartados fundamentales para saber interpretar un DUMP. Nos dice el punto exacto, con su posición dentro del código. Además, y más importante, si hacemos click entraremos dentro del código en cuestión. Con esto podemos poner un break point y volver a probar el proceso que da error para ver el motivo en debugging.,  Tambien llegamos al código pulsando el icono Editor ABAP de la barra de herramientas superior.


Llamadas/Eventos activos

Apartado también fundamental. Nos dice la pila de llamadas que se han ido haciendo para hasta llegar al código que nos da error. Esto es importante porque, en ocasiones, el origen del error no está en el código que ha fallado, sino que es consecuencia de algo que ha pasado antes. Por ejemplo, si no le pasamos una referencia a un objeto instanciada a un método subordinado, posiblemente el código dentro de ese método de error, pero el origen es anterior. Otro ejemplo, si no manejamos la excepción que devuelve un código subordinado, la excepción la da ese código, pero si ponemos un TRY-CATCH en el inmediatamente superior podemos arreglarlo.


Resto de apartados

El resto de apartados de un DUMP:

  • Entorno sistema 
  • Usuario y transacción 
  • Serverseitige Verbindungsinformationen
  • Contenido campos sistema
  • Variables seleccionadas
  • Llamadas de aplicación
  • Lista de programas ABAP implicados 
  • Notas internas
  • Llamadas activas núcleo SAP
  • Directorio de tablas de aplicación
  • Bloq.control ABAP (CONT) (Texto fuente modificado) 

No los considero fundamentales para la investigación y descubrir el motivo del error. Seguro que alguno habrá importante, pero yo no los uso.


Recepción de emails sobre DUMPs

Ahora bien, una vez visto como buscar e interpretar un DUMPs, tenemos claro que si estamos ejecutando un proceso y nos da un error podemos saber donde ir a verlo y cómo interpretarlo. Pero ¿si el DUMP se genera en un proceso en fondo? ¿Si es en producción por un usuario del sistema? ¿Cómo podemos enterarnos de que ha sucedido? ¿Tenemos que estar entrando todos los días varias veces a comprobarlo o esperar la incidencia?. No, para eso tenemos la posibilidad de que el sistema nos mande mails de los DUMPs.

Para eso tenemos tres opciones por un lado podemos crear un job en fondo sobre el report RSSHOWRABAX con una variante del día anterior.

Job Sobre el report RSSHOWRABAX

Luego programamos un job sobre este report con la variante que hemos creado.

Le damos al botón Destino Listas SPOOL e introducimos nuestra dirección de correo.

Elegimos la periodicidad

Y al ejecutar veremos el mail saliente en la SOST

Nota 176492 – Automatic email when an alert occurs (RZ20)

Podemos ver en la nota de SAP «176492 – Automatic email when an alert occurs (RZ20)» la forma de, usando la RZ20 y el CCMS cada vez que se produzca un DUMP recibir un mail de alerta. Pero el procedimiento de alta de esta alerta es realmente complejo, con acceso al mandante 000 incluso. No lo veo muy claro.

También te lo explican en foros de la SAP como:


Report Z de consulta y envío de DUMPs

Hay otra opción, más rudimentaria pero más controlada, es crearnos nuestro propio Report de consulta, recopilación y envío de Dumps vía email. Para ello tendremos que hacer nuestra selección de datos en la tabla que almacena los DUMPs, la SNAP. A continuación os pongo un ejemplo desarrollado por mi, esto pasado a un JOB diario nos da una idea de los DUMPs ocurridos el día, también se puede hacer algo más inmediato programandolo cada hora o incluso como un demonio en el sistema.

&---------------------------------------------------------------------*
*& Report ZJOB_SEND_DUMPS
*&---------------------------------------------------------------------*
*&
*& Autor: Jorge Ocampos
*& Descripción: Program that collects the Dumps of the system at a given
*&              time by the selection and sends an e-mail with the summary
*&---------------------------------------------------------------------*
REPORT zjob_send_dumps.

*&---------------------------------------------------------------------*
*                T A B L E S
*&---------------------------------------------------------------------*
TABLES: somlreci1.

*&---------------------------------------------------------------------*
*                D A T A   T Y P E S
*&---------------------------------------------------------------------*
TYPES: BEGIN OF ty_text_dump,
         id    TYPE c LENGTH 2,
         ll    TYPE c LENGTH 3,
         errid TYPE snapt-errid,
       END OF ty_text_dump.

TYPES: BEGIN OF ty_data,
         datum TYPE string,
         uzeit TYPE string,
         uname TYPE snap-uname,
         errid TYPE snapt-errid,
       END OF ty_data.


*&---------------------------------------------------------------------*
*               V A R I A B L E S
*&---------------------------------------------------------------------*
DATA: ls_text_dump TYPE ty_text_dump,
      gt_data      TYPE TABLE OF ty_data,
      gt_objtxt    TYPE STANDARD TABLE OF solisti1,
      gt_objpack   TYPE STANDARD TABLE OF sopcklsti1,
      gs_docdata   TYPE sodocchgi1,
      gt_objhead   TYPE STANDARD TABLE OF solisti1.


*&---------------------------------------------------------------------*
*                S E L E C T I O N - S C R E E N
*&---------------------------------------------------------------------*
SELECTION-SCREEN BEGIN OF BLOCK b1 WITH FRAME TITLE TEXT-001.

  SELECT-OPTIONS: s_datum FOR sy-datum.

SELECTION-SCREEN END OF BLOCK b1.


SELECTION-SCREEN BEGIN OF BLOCK b2 WITH FRAME TITLE TEXT-004.

  SELECT-OPTIONS: s_mail FOR somlreci1-receiver NO INTERVALS DEFAULT 'tu mail' OBLIGATORY.

SELECTION-SCREEN END OF BLOCK b2.



*&---------------------------------------------------------------------*
*                S T A R T - O F - S E L E C T I O N
*&---------------------------------------------------------------------*
START-OF-SELECTION.

  PERFORM get_data.

  IF gt_data IS NOT INITIAL.

    PERFORM create_message.

    PERFORM send_message.
  ELSE.
    WRITE:/ 'NO DUMPs in selection!!'.
  ENDIF.

*&---------------------------------------------------------------------*
*                F O R M S
*&---------------------------------------------------------------------*
*&VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV*
*&---------------------------------------------------------------------*
*& Form get_data
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
FORM get_data.

  DATA: ls_data TYPE ty_data.

  SELECT * INTO TABLE @DATA(lt_snap_beg)
                 FROM snap_beg
                WHERE datum IN @s_datum
                  AND seqno = '000'
             ORDER BY datum,
                      uzeit.

  IF sy-subrc = 0.
    DESCRIBE TABLE lt_snap_beg LINES DATA(lv_lines).
    LOOP AT lt_snap_beg INTO DATA(ls_snap_beg).
      ls_text_dump = ls_snap_beg-flist.
      ls_text_dump-errid = ls_text_dump-errid(ls_text_dump-ll).

      MOVE-CORRESPONDING ls_snap_beg TO ls_data.
      ls_data-errid = ls_text_dump-errid.
      CONCATENATE ls_data-datum+6(2)
                  ls_data-datum+4(2)
                  ls_data-datum(4) INTO ls_data-datum SEPARATED BY '/'.
      CONCATENATE ls_data-uzeit(2)
                  ls_data-uzeit+2(2)
                  ls_data-uzeit+4(2) INTO ls_data-uzeit SEPARATED BY ':'.

      INSERT ls_data INTO TABLE gt_data.
      WRITE:/ ls_data-datum, ls_data-uzeit, ls_snap_beg-uname, ls_text_dump-errid.
    ENDLOOP.
  ENDIF.
ENDFORM.
*&---------------------------------------------------------------------*
*& FORM create_message
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
FORM create_message.

  DATA: ls_data    TYPE ty_data,
        ls_objpack TYPE sopcklsti1.

  " Title
  gs_docdata-obj_name  = 'email notification'.

  " Description
  gs_docdata-obj_descr = 'DUMPs overview'.

  PERFORM add_mail_line USING '<html> <body style="background-color:#ffe4c4;">'.
  PERFORM add_mail_line USING 'List of DUMPs:'.
  PERFORM add_mail_line USING '<table style="margin: 10px" cellspacing="0″ cellpadding="3″ width="800″ border="1″><tbody><tr>'.
  PERFORM add_mail_line USING '<th>Day</font></th>'.
  PERFORM add_mail_line USING '<th>Time</font></th>'.
  PERFORM add_mail_line USING '<th>User</font></th>'.
  PERFORM add_mail_line USING '<th>DUMP</font></th>'.

*   table Contents
  LOOP AT gt_data INTO ls_data.

    PERFORM add_mail_table_line USING '<tr><td><center>'
                                      ls_data-datum
                                      '</center></td>'.
    PERFORM add_mail_table_line USING '<td><center>'
                                      ls_data-uzeit
                                      '</center></td>'.
    PERFORM add_mail_table_line USING '<td><center>'
                                      ls_data-uname
                                      '</center></td>'.
    PERFORM add_mail_table_line USING '<td><center>'
                                      ls_data-errid
                                      '</center></td>'.
  ENDLOOP.

  PERFORM add_mail_line USING '</tbody> </table> </body> </html> '.


  DESCRIBE TABLE gt_objtxt LINES DATA(lv_lines).

  READ TABLE gt_objtxt INTO DATA(wa_objtxt) INDEX lv_lines.

  gs_docdata-doc_size = ( lv_lines - 1 ) * 255 + strlen( wa_objtxt ).

* Packing data

  CLEAR ls_objpack-transf_bin.
  ls_objpack-head_start = 1.
  ls_objpack-head_num   = 0.
  ls_objpack-body_start = 1.
  ls_objpack-body_num   = lv_lines.
  ls_objpack-doc_type   = 'HTML'.
  APPEND ls_objpack TO gt_objpack.

ENDFORM.
*&---------------------------------------------------------------------*
*& FORM send_message
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
FORM send_message .

  DATA: lt_receivers TYPE TABLE OF somlreci1,
        ls_receiver  TYPE somlreci1.
  LOOP AT s_mail INTO DATA(ls_mail).
    ls_receiver-receiver = s_mail-low.
    ls_receiver-rec_type = 'U'.
    INSERT ls_receiver INTO TABLE lt_receivers.
  ENDLOOP.

*   Send Message to external Internet ID
  CALL FUNCTION 'SO_NEW_DOCUMENT_ATT_SEND_API1'
    EXPORTING
      document_data              = gs_docdata
      put_in_outbox              = 'X'
      commit_work                = 'X'
    TABLES
      packing_list               = gt_objpack
*     object_header              = gt_objhead
      contents_txt               = gt_objtxt
      receivers                  = lt_receivers
    EXCEPTIONS
      too_many_receivers         = 1
      document_not_sent          = 2
      document_type_not_exist    = 3
      operation_no_authorization = 4
      parameter_error            = 5
      x_error                    = 6
      enqueue_error              = 7
      OTHERS                     = 8.

ENDFORM.
*&---------------------------------------------------------------------*
*& Form add_line
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
FORM add_mail_line USING p_var.

  DATA: ls_objtxt  TYPE solisti1.

  ls_objtxt-line = p_var.

  APPEND ls_objtxt TO gt_objtxt.

ENDFORM.
*&---------------------------------------------------------------------*
*& Form add_line
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
FORM add_mail_table_line USING p_var1
                               p_var2
                               p_var3.

  DATA: ls_objtxt  TYPE solisti1.

  CONCATENATE p_var1
              p_var2
              p_var3 INTO ls_objtxt-line.

  APPEND ls_objtxt TO gt_objtxt.

ENDFORM.

Como este artículo se ha quedado un poco extenso y hay más cosas que contar abordaremos más información en otros artículos posteriores.

3 comentarios sobre “Errores en SAP – DUMPs

Deja un comentario