SAP Netweaver / ABAP                  Notas técnicas / Tips / Tutorials

ABAP Objects: Tutorial para implementar "exceptions"

En este Tutorial de ABAP Objects conoceremos qué es una excepción ("exception") y veremos en qué situaciones conviene usarlas. Además, aprenderemos a implementarlas en ABAP Objects, y probaremos su uso mediante dos ejemplos, paso a paso.

Una Excepción ("Exception") es un evento que ocurre durante la ejecución de un programa, que interrumpe el flujo normal de las instrucciones del mismo, cambiando su normal comportamiento. Cuando se produce una excepción (usualmente asociada a una condición de error), el programa termina inmediatamente, por lo tanto, es importante que esas situaciones puedan ser manejadas de alguna manera dentro del programa y evitar la cancelación del mismo.

 

Mencionamos anteriormente que las excepciones usualmente indican una condición de error. Por ejemplo, la operación de división no es posible cuando el divisor es cero. En tal caso va a ocurrir un error en tiempo de ejecución, y cancelaría el programa. Un modo de "manejar" una excepción dentro del programa y presentar la interrupción al usuario de manera "más amigable", podría mostrar en este caso un cartel indicando el error del por qué no se puede realizar tal operación, y permitir al usuario un nuevo ingreso de datos.

En este tip veremos cómo se manejan las excepciones ("exceptions") en ABAP Objects y dos ejemplos donde se codifica su uso.

Excepciones en ABAP objects

Cuando se programa en ABAP estructurado, las excepciones se manejan de manera genérica con el bloque CATCH - ENDCATCH. En particular, si se trata de un error aritmético (por ejemplo la división por cero), el error puede ser manejado en ABAP mediante el grupo de excepciones ARITHMETIC_ERRORS. En este caso la instrucción a usar sería: CATCH SYSTEM-EXCEPTIONS arithmetic-errors.

En ABAP OO, las excepciones son representadas por una instancia de una clase excepción. Los atributos de ese objeto van a contener información acerca de la situación ocurrida. Una excepción puede ser “levantada” con la sentencia RAISE EXCEPTION. Cuando esto ocurre, el sistema busca un manejador adecuado que se haga cargo, y en el caso de no encontrarlo, se produce un error en tiempo de ejecución. Este manejo se puede llevar únicamente a cabo si la sentencia que podría ocasionar que se levante la excepción, se encuentra encerrada por el bloque TRY-ENDTRY.

El manejo de la excepción se realiza específicamente con la instrucción CATCH que se encuentra dentro del bloque.

El siguiente es un código genérico que muestra la estrcutura del TRY-ENDTRY conteniendo la CATCH que maneja la excepción. Más adelante se mostrarán ejemplos concretos donde que utilizan estas sentencias para el manejo de excepciones.

TRY.

SENTENCIA_X.

CATCH cx_exc_1 INTO ref_exc_1.

CATCH cx_exc_2 INTO ref_ex_2.

CLEANUP.

ENDTRY.

donde:

  • SENTENCIA_X” puede ser una subrutina, un módulo de función, un método u otro objeto que pueda lanzar una o más excepciones.
  • ref_exc_i es una instancia de la clase “cx_exc_i" o de alguna superclase ( “cx_root" por ejemplo, como se va a ver más adelante).
  • La ejecución del código que puede estar incluido en el bloque CLEANUP, se produce cuando el sistema no encuentra un manejador para la excepción que fue levantada (no existe CATCH) y se usa en general para "propagar" la excepción, es decir, volver a levantarla. Como ejemplo, si la “SENTENCIA_X” levanta la excepción cx_exc_3 y no existe un CATCH para la misma, ejecutará las instrucciones que se encuentren en el bloque CLEANUP siempre y cuando se cumplan ciertas condiciones:

- Una excepción es levantada en el área protegida.

- La excepción no es manejada en el bloque TRY-ENDTRY (como se dijo anteriormente), pero sí en algún punto de la jerarquía.

 

Tener en cuenta que se puede utilizar el mismo manejador (CATCH) para dos excepciones diferentes. Entonces, la siguiente sentencia es válida:

CATCH cx_exc_1 cx_exc_2 INTO ref_exc.

Ejemplos de manejo de excepciones en ABAP Objects:

A continuación mostraremos dos ejemplos de manejo de excepciones. En el primero se va a utilizar y manejar una excepción definida por SAP. En el segundo se creará una nueva clase excepción y se van a definir algunos atributos.

Ejemplo 1: División por cero

Código del programa de prueba:

*&---------------------------------------------------------------------*

*& Include Z_EXCEPCION_PRUEBA_TOP Report Z_EXCEPCION_PRUEBA

*&

*&---------------------------------------------------------------------*

 

REPORT z_excepcion_prueba.

 

TYPES ty_numero TYPE p LENGTH 4 DECIMALS 2.

 

DATA: resultado TYPE ty_numero,

ref_exc TYPE REF TO cx_root,

msg TYPE string.

 

PARAMETERS:

pa_num1 TYPE ty_numero,

pa_num2 TYPE ty_numero.

 

 

*&---------------------------------------------------------------------*

*& Report Z_EXCEPCION_PRUEBA

*&

*&---------------------------------------------------------------------*

*&

*&

*&---------------------------------------------------------------------*

INCLUDE z_excepcion_prueba_top . " global Data

TRY.

resultado = pa_num1 / pa_num2.

WRITE: 'El resultado es: ', resultado.

 

CATCH cx_sy_zerodivide INTO ref_exc.

msg = ref_exc->get_text( ).

MESSAGE msg TYPE 'I'.

ENDTRY.

 

1) El código de arriba incorpora el bloque TRY - ENDTRY para capturar el error. Por lo tanto, al ejecutar el programa, si se ingresa un cero como divisor ocurrirá lo mostrado a continuación, donde luego deberá ingresar otro valor distinto de cero, para salir del error:

ABAP-Objects-1-ejecucion-ejemplo1.1

Notar que el método get_text() que se utilizó en el ejemplo es el que implementa la clase CX_ROOT de la interfaz IF_MESSAGE, el cual es heredado por toda la cadena de subclases hasta llegar a CX_SY_ZERODIVIDE (ver más abajo jerarquía de clases para comprender su comportamiento).

2) En cambio, si se comenta el bloque TRY-ENDTRY y sólo se deja la sentencia que realiza la división, el sistema desplegará el siguiente mensaje en tiempo de ejecución cuando el divisor sea cero:

ABAP-Obejcts-2_ejecucion_ejemplo1.2

En este caso, el error ocurre porque la excepción no fue manejada. El sistema levanta automáticamente la excepción en la sentencia que realiza la división cuando el divisor es cero. Por lo tanto, como no existe un manejador de tal excepción (la sentencia no se encuentra encerrada en un bloque try-catch) se produce un error en tiempo de ejecución.

Se puede observar en el primer paso, cómo el manejo de la excepción logró una interacción más amigable con el usuario.

Jerarquía de clases Exceptions

La excepción capturada en el ejemplo anterior proviene de una clase standard de SAP llamada CX_SY_ZERODIVIDE.

Para visualizar el arbol de jerarquía de clases "exceptions":

  • Ir a la solapa “Properties” de la clase CX_SY_ZERODIVIDE.

ABAP-Objects-3_clase_cx_sy_zerodivide

  • Notar que la clase hereda de una superclase. Si se hace doble click a la superclase CX_SY_ARITHMETIC_ERROR, se puede acceder a la misma. De esta forma se puede ver el árbol jerárquico de herencia hasta llegar a la clase padre CX_ROOT, que es la clase raíz de todas las excepciones.

La jerarquía básica de herencia de excepciones en ABAP se puede ver en la siguiente ilustración:

ABAP-Objects-4_jerarquia_excepciones

 

Ejemplo 2: Creación y utilización de una clase excepción

Para este ejemplo se va a definir una clase PERRO que tenga como atributos el nombre y peso. Se desea que el constructor de la clase "levante" una excepción cuando se intente instanciar un objeto de la clase PERRO con peso negativo o igual a cero.

Se mostrará por pantalla dos mensajes diferentes para cada situación:

  • En el caso que el número sea negativo el mensaje será: “El peso de <nombre_perro> no puede ser negativo”.
  • En cambio, en el caso que sea igual a cero, el mensaje dirá: <nombre_perro> no puede no pesar nada"


Luego se creará un programa de prueba que maneje dichas excepciones y en los casos que corresponda, mostrará los mensajes mencionados previamente.

Los pasos a llevar a cabo son:

1. Se crea la clase Z_PERRO y se declaran los atributos nombre y peso. Los tipos asociados son “string” y “int2”, respectivamente.

ABAP-Objects-5_clase_z_perro_atributos

2. En la solapa de “Methods” se declara el constructor y se definen los siguientes parámetros:

ABAP-Objects-6_clase_z_perro_metodos

3. Posteriormente, volver a la lista de métodos, seleccionar el constructor y oprimir el botón “Exceptions”. Declarar la excepción ZCX_PESO_INVALIDO, presionar “Enter” para crearla, y finalmente oprimir “Save” en la ventana emergente:

ABAP-Objects-7_creacion_excepcion-1

 

4. Dentro de la clase ZCX_PESO_INVALIDO, en la solapa “Texts” definir el texto que se muestra a continuación para el ID ZCX_PESO_INVALIDO (note que el ID se llama igual que la clase y ya viene definido). Ingresar un nuevo ID llamado ZCX_PESO_INVALIDO_CERO y completar el texto como se indica:

ABAP-Objects-8_clase_excepcion_texts

Notar que en la solapa de atributos se crearon automáticamente dos constantes con los nombres de ambos ID’s (el que ya estaba definido y el que nuevo que se definió), cuyos valores se generaron automáticamente. Agregar el atributo nombre con tipo “string”.

ABAP-Objects-9_clase_excepcion_atributos

5. Activar la clase ZCX_PESO_INVALIDO. Posteriormente volver a la clase Z_PERRO y escribir el código para la implementación del método CONSTRUCTOR.

Código para la Implementación del método CONSTRUCTOR:

METHOD constructor.

 

IF i_peso LT 0.

 

RAISE EXCEPTION TYPE zcx_peso_invalido

EXPORTING

nombre = i_nombre.

ELSEIF i_peso EQ 0.

 

RAISE EXCEPTION TYPE zcx_peso_invalido

EXPORTING

textid = zcx_peso_invalido=>zcx_peso_invalido_cero

nombre = i_nombre.

ELSE.

nombre = i_nombre.

peso = i_peso.

ENDIF.

ENDMETHOD.

6. Activar la clase Z_PERRO.

A continuación se muestra un programa de prueba que maneja la excepción.

Código del programa de prueba que maneja la excepción:

*&---------------------------------------------------------------------*

*& Report Z_PERRO_PRUEBA

*&

*&---------------------------------------------------------------------*

*&

*&

*&---------------------------------------------------------------------*

 

REPORT Z_PERRO_PRUEBA.

 

DATA: un_perro TYPE REF TO Z_PERRO,

ref_exc TYPE REF TO cx_root,

msg TYPE string.

 

TRY.

 

CREATE OBJECT un_perro

EXPORTING

i_nombre = 'Lazy'

i_peso = 0.

 

WRITE: 'Lazy creado exitosamente'.

 

CATCH zcx_peso_invalido INTO ref_exc.

 

msg = ref_exc->get_text( ).

MESSAGE msg type 'I'.

 

ENDTRY.

 

TRY.

 

CREATE OBJECT un_perro

EXPORTING

i_nombre = 'Milu'

i_peso = -10.

 

WRITE: 'Milu creado exitosamente'.

 

CATCH zcx_peso_invalido INTO ref_exc.

 

msg = ref_exc->get_text( ).

MESSAGE msg type 'I'.

 

ENDTRY.

 

TRY.

 

CREATE OBJECT un_perro

EXPORTING

i_nombre = 'Budy'

i_peso = 30.

 

WRITE: 'Budy creado exitosamente'.

 

CATCH zcx_peso_invalido INTO ref_exc.

 

msg = ref_exc->get_text( ).

MESSAGE msg type 'I'.

 

ENDTRY.

8. Ejecutar el programa y ver los mensajes que se muestran por pantalla. Observar que el único objeto que se crea es el último (“Budy”), porque cuando se intenta crear los objetos "Lazy" y "Milu" el método constructor levanta la excepción, por lo tanto se ejecuta únicamente el bloque CATCH dentro del bloque TRY-ENDTRY.

Consideraciones adicionales para el Ejemplo 2

Analizando la implementación del método CONSTRUCTOR, observar que en el caso que el peso sea negativo, se levantó la excepción con la primera instrucción RAISE EXCEPTION pero no se exportó el parámetro “textid” . Este parámetro toma por default la constante que tiene el mismo nombre que la clase Z_PESO_INVALIDO, por lo tanto, no necesita ser exportada. Observar que el texto que corresponde a la constante es “El peso de &nombre& no puede ser negativo”.

En la segunda sentencia RAISE EXCEPTION, se exporta el “textid” correspondiente a cuando el peso es igual a cero (la constante Z_PESO_INVALIDO_CERO). Como es necesario que el texto cambie, se requiere explicitar el parámetro "textid".


n_Guido-Falcucci Especialista ABAP

Copyright 2013 - Teknoda S.A.

IMPORTANTE:
“Notas técnicas de SAP ABAP" se envía con frecuencia variable y sin cargo como servicio a nuestros clientes SAP. Contiene notas/tutoriales/artículos técnicos desarrollados en forma totalmente objetiva e independiente. Teknoda es una organización de servicios de tecnología informática y NO comercializa hardware, software ni otros productos.
Si desea suscribir otra dirección de e-mail para que comience a recibir las Notas Técnicas SAP, envíe un mensaje desde esa direcciónsapping@teknoda.com, aclarando nombre, empresa, cargo y país del suscriptor.

SAP, Netweaver, R/3, Fiori,S4/HANA y ABAP son marcas registradas de SAP AG. SAP no es el editor de esta publicación y no es responsable de la misma en ningún aspecto. La información contenida en esta publicación ha sido generada por nuestros especialistas a partir de fuentes consideradas confiables y del ejercicio profesional cotidiano. No obstante, por la posibilidad de error humano, mecánico, cambio de versión u otro, Teknoda no garantiza la exactitud o completud de la misma.
COPYRIGHT TEKNODA S.A. PROHIBIDA SU REPRODUCCION TOTAL O PARCIAL SIN CONSENTIMIENTO DE TEKNODA

 


 

Copyright © 2024 Teknoda Tech Portal & Training. Todos los derechos reservados.
Joomla! es software libre, liberado bajo la GNU General Public License.