Está en la página 1de 9

ABAP Objects: Tutorial para implementar "exceptions"

En este Tutorial de ABAP Objects conoceremos qu es una excepcin ("exception") y veremos en


qu situaciones conviene usarlas. Adems, aprenderemos a implementarlas en ABAP Objects, y
probaremos su uso mediante dos ejemplos, paso a paso.
Una Excepcin ("Exception") es un evento que ocurre durante la ejecucin de un programa, que interrumpe
el flujo normal de las instrucciones del mismo, cambiando su normal comportamiento. Cuando se produce
una excepcin (usualmente asociada a una condicin 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 cancelacin del mismo.

Mencionamos anteriormente que las excepciones usualmente indican una condicin de error. Por ejemplo, la
operacin de divisin no es posible cuando el divisor es cero. En tal caso va a ocurrir un error en
tiempo de ejecucin, y cancelara el programa. Un modo de "manejar" una excepcin dentro del
programa y presentar la interrupcin al usuario de manera "ms amigable", podra mostrar en este caso un
cartel indicando el error del por qu no se puede realizar tal operacin, y permitir al usuario un nuevo ingreso
de datos.
En este tip veremos cmo 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 genrica con el
bloque CATCH - ENDCATCH. En particular, si se trata de un error aritmtico (por ejemplo la divisin por
cero), el error puede ser manejado en ABAP mediante el grupo de excepciones ARITHMETIC_ERRORS.
En este caso la instruccin a usar sera: CATCH SYSTEM-EXCEPTIONS arithmetic-errors.
En ABAP OO, las excepciones son representadas por una instancia de una clase excepcin.
Los atributos de ese objeto van a contener informacin acerca de la situacin ocurrida. Una excepcin
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
ejecucin. Este manejo se puede llevar nicamente a cabo si la sentencia que podra ocasionar que se
levante la excepcin, se encuentra encerrada por el bloque TRY-ENDTRY.
El manejo de la excepcin se realiza especficamente con la instruccin CATCH que se encuentra dentro del
bloque.
El siguiente es un cdigo genrico que muestra la estrcutura del TRY-ENDTRY conteniendo la CATCH que
maneja la excepcin. Ms adelante se mostrarn 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 mdulo de funcin, un mtodo u otro
objeto que pueda lanzar una o ms 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 ms adelante).
La ejecucin del cdigo que puede estar incluido en el bloque CLEANUP, se produce
cuando el sistema no encuentra un manejador para la excepcin que fue levantada (no existe
CATCH) y se usa en general para "propagar" la excepcin, es decir, volver a levantarla. Como
ejemplo, si la SENTENCIA_X levanta la excepcin 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 excepcin es levantada en el rea protegida.
- La excepcin no es manejada en el bloque TRY-ENDTRY (como se dijo anteriormente), pero s en algn
punto de la jerarqua.

Tener en cuenta que se puede utilizar el mismo manejador (CATCH) para dos excepciones
diferentes. Entonces, la siguiente sentencia es vlida:
CATCH cx_exc_1 cx_exc_2 INTO ref_exc.
Ejemplos de manejo de excepciones en ABAP Objects:
A continuacin mostraremos dos ejemplos de manejo de excepciones. En el primero se va autilizar y
manejar una excepcin definida por SAP. En el segundo se crear una nueva clase
excepcin y se van a definir algunos atributos.
Ejemplo 1: Divisin por cero
Cdigo 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 cdigo 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 continuacin, donde luego deber
ingresar otro valor distinto de cero, para salir del error:

Notar que el mtodo get_text() que se utiliz en el ejemplo es el que implementa la claseCX_ROOT de la
interfaz IF_MESSAGE, el cual es heredado por toda la cadena de subclases hasta llegar
a CX_SY_ZERODIVIDE (ver ms abajo jerarqua de clases para comprender su comportamiento).
2) En cambio, si se comenta el bloque TRY-ENDTRY y slo se deja la sentencia que realiza la divisin, el
sistema desplegar el siguiente mensaje en tiempo de ejecucin cuando el divisor sea cero:
En este caso, el error ocurre porque la excepcin no fue manejada. El sistema levanta
automticamente la excepcin en la sentencia que realiza la divisin cuando el divisor es cero. Por lo tanto,
como no existe un manejador de tal excepcin (la sentencia no se encuentra encerrada en un bloque try-
catch) se produce un error en tiempo de ejecucin.
Se puede observar en el primer paso, cmo el manejo de la excepcin logr una interaccin ms amigable
con el usuario.
Jerarqua de clases Exceptions
La excepcin capturada en el ejemplo anterior proviene de una clase standard de SAP
llamada CX_SY_ZERODIVIDE.
Para visualizar el arbol de jerarqua de clases "exceptions":
Ir a la solapa Properties de la clase CX_SY_ZERODIVIDE.

Notar que la clase hereda de una superclase. Si se hace doble click a la


superclaseCX_SY_ARITHMETIC_ERROR, se puede acceder a la misma. De esta forma se puede
ver el rbol jerrquico de herencia hasta llegar a la clase padre CX_ROOT, que es la clase raz
de todas las excepciones.
La jerarqua bsica de herencia de excepciones en ABAP se puede ver en la siguiente ilustracin:

Ejemplo 2: Creacin y utilizacin de una clase excepcin


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 excepcin 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 situacin:
En el caso que el nmero 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.

2. En la solapa de Methods se declara el constructor y se definen los siguientes parmetros:

3. Posteriormente, volver a la lista de mtodos, seleccionar el constructor y oprimir el botn Exceptions.


Declarar la excepcin ZCX_PESO_INVALIDO, presionar Enter para crearla, y finalmente oprimir Save
en la ventana emergente:
4. Dentro de la clase ZCX_PESO_INVALIDO, en la solapa Texts definir el texto que se muestra a
continuacin 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:

Notar que en la solapa de atributos se crearon automticamente dos constantes con los nombres de
ambos IDs (el que ya estaba definido y el que nuevo que se defini), cuyos valores se generaron
automticamente. Agregar el atributo nombre con tipo string.
5. Activar la clase ZCX_PESO_INVALIDO. Posteriormente volver a la clase Z_PERRO y escribir el cdigo
para la implementacin del mtodo CONSTRUCTOR.
Cdigo para la Implementacin del mtodo 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 continuacin se muestra un programa de prueba que maneja la excepcin.
Cdigo del programa de prueba que maneja la excepcin:
*&-------------------------------------------------------------------
--*
*& 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 elnico objeto
que se crea es el ltimo (Budy), porque cuando se intenta crear los objetos "Lazy" y "Milu" el mtodo
constructor levanta la excepcin, por lo tanto se ejecuta nicamente el bloque CATCH dentro del bloque TRY-
ENDTRY.
Consideraciones adicionales para el Ejemplo 2
Analizando la implementacin del mtodo CONSTRUCTOR, observar que en el caso que elpeso sea
negativo, se levant la excepcin con la primera instruccin RAISE EXCEPTIONpero no se export el
parmetro textid . Este parmetro 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 parmetro "textid".

También podría gustarte