Manejo de excepciones

Se puede producir un error cuando un programa generado por EGL actúa de la manera siguiente:

Bloques try

Un bloque try EGL es una serie de cero a muchas sentencias EGL que están dentro de los delimitadores try y end. A continuación se ofrece un ejemplo:
  if (userRequest = "A")
    try
      add record1;
    onException
      myErrorHandler(12);
    end
  end

En general, un bloque try permite que el programa se siga procesando aunque se produzca un error.

El bloque try puede incluir una cláusula onException, como se ha mostrado en el ejemplo anterior. Esta cláusula se invoca si falla una de las sentencias anteriores del bloque try; pero en ausencia de una cláusula onException, un error en un bloque try hace que se invoque la primera sentencia que sigue inmediatamente al bloque try.

Excepciones del sistema

EGL proporciona una serie de excepciones del sistema para indicar la naturaleza específica de un problema de tiempo de ejecución. Cada una de estas excepciones es un diccionario desde el que puede recuperar información, pero la recuperación siempre se hace por medio de la variable del sistema SysLib.currentException (también un diccionario), que permite acceder a la excepción mostrada más recientemente en la unidad de ejecución.

Un campo de cualquier excepción es code, que es una serie que identifica la excepción. Puede determinar la excepción actual probando ese campo en la lógica de la forma siguiente:
  if (userRequest = "A")
    try
      add record1;
    onException
      case (SysLib.currentException.code)
        when (FileIOException)
          myErrorHandler(12);
        otherwise
          myErrorHandler(15);
      end
    end
  end

En este caso, FileIOException es una constante que es equivalente al valor de serie "com.ibm.egl.FileIOException". La constante de excepción de EGL siempre es equivalente al último calificador de una serie que empieza por "com.ibm.egl".

Se recomienda encarecidamente que acceda a los campos de excepción solo en un bloque onException. La unidad de ejecución termina si el código accede a SysLib.currentException cuando no se ha producido ninguna excepción.

El ejemplo siguiente accede al campo sqlcode en la excepción SQLException:
  if (userRequest = "A")
    try
      add record01;
    onException
      case (SysLib.currentException.code)
        when ("com.ibm.egl.SQLException")
          if (SysLib.currentException.sqlcode == -270)
            myErrorHandler(16);
          else
            myErrorHandler(20);
          end
        otherwise
          myErrorHandler(15);
      end
    end
  end

Para conocer más detalles sobre las excepciones del sistema, consulte Excepciones del sistema EGL.

Límites de los bloques try

Los detalles anteriores sobre los bloques try deben estar calificados. En primer lugar, un bloque try sólo afecta al proceso de errores en los siguientes tipos de sentencias EGL:
  • Una sentencia de E/S
  • Una función de sistema
  • Una sentencia call

El proceso de los desbordamientos numéricos no se ve afectado por la presencia de un bloque try. Para obtener información detallada sobre estos tipos de error, consulte la sección VGVar.handleOverflow.

En segundo lugar, un bloque try no tiene ningún efecto sobre los errores de una función de usuario (o programa) que se invoca desde dentro del bloque try. En el siguiente ejemplo, si una sentencia falla en la función myABC, el programa finaliza inmediatamente con un mensaje de error a menos que la propia función myABC maneje el error:
  if (userRequest = "B")
    try
      myVariable = myABC();
    onException
      myErrorHandler(12);
    end
  end
En tercer lugar, el programa finaliza inmediatamente y con un mensaje de error en los siguientes casos:
  • Un error de un tipo que está incluido específicamente en un bloque try se produce fuera de un bloque try; o bien
  • Se aplica uno de los siguientes casos, incluso en un bloque try:
    • Una función escrita por el usuario falla en la invocación o en el retorno al invocante;
    • La variable de sistema VGVar.handleHardIOErrors se establece en cero cuando un archivo o sentencia de E/S MQSeries finaliza con un error grave (como se describe más adelante); o bien
    • Las variables de sistema DLIVar.handleHardDLIErrors y VGVar.handleHardIOErrors se establecen en cero cuando un intento de acceder a una cola IMS de datos o a una base de datos DL/I finaliza con un error grave.
Los casos siguientes también son de interés:
  • Si un valor se divide por cero, un programa Java maneja la situación como un desbordamiento numérico
  • Una unidad de ejecución Java finaliza si se asigna un carácter no numérico a una variable numérica del descriptor de construcción
Para dar soporte a la migración de programas escritos en VisualAge Generator y EGL 5.0, la variable VGVar.handleSysLibraryErrors (anteriormente llamada EZEREPLY) permite procesar algunos errores que se producen fuera de un bloque try. Evite utilizar esa variable, que sólo está disponible si trabaja en modalidad de compatibilidad de VisualAge Generator.

Variables de sistema relacionadas con errores

EGL proporciona variables de sistema relacionadas con errores que se establecen en un bloque try como respuesta a eventos satisfactorios o como respuesta a errores de no terminación. Los valores de dichas variables están disponibles en el bloque try y en el código que se ejecuta después del bloque try y, en la mayoría de los casos, los valores se restauran después de una sentencia converse, si existe.

Dentro de un bloque try, se aplican las siguientes normas:
  • Se otorga un valor a la variable del sistema sysVar.errorCode después de ejecutar cualquiera de las especies de sentencias siguientes:
    • Una sentencia call
    • Una sentencia de E/S que actúa sobre un archivo indexado, MQ, relativo o serie
    • Una invocación de casi cualquier función de sistema
  • Después de aplicar una sentencia de E/S sobre un registro MQ, se otorgan valores a las variables del sistema sysVar.errorCode y VGVar.mqConditionCode
  • Después de acceder a una base de datos relacional en un bloque try, se asignan valores a las variables en el área de comunicación SQL (SQLCA); para conocer más detalles, consulte SysVar.sqlca
  • Después de acceder a una base de datos DL/I, se asignan valores a las variables de estado de PCB (DLIVar.dbName, DLIVar.keyArea, DLIVar.keyAreaLen, DLIVar.segmentLevel, DLIVar.procOptions, DLIVar.segmentName, DLIVar.numSensitiveSegs y DLIVar.statusCode).

    Si está ejecutando en CICS, también se asignan valores a las variables de estado de DL/I de CICS (DLIVar.cicsError, DLIVar.cicsCondition y DLIVar.cicsRestart).

El tiempo de ejecución de EGL no establece las variables relacionadas con DL/I que se han listado anteriormente después de que el código acceda a un archivo GSAM o a un acceso de cola de mensajes de IMS. Se considera que ese acceso es un acceso de archivo en serie. Para obtener acceso a información de estado adicional en esos casos, utilice el registro PCB adecuado. Para obtener una visión general, consulte Soporte de EGL para PSB y PCB de tiempo de ejecución. Para obtener detalles acerca de tipos determinados de registros de PCB, consulte Tipos y propiedades de registro.

Se asigna un código de error a sysVar.errorCode en el caso de un desbordamiento numérico de no terminación, como se describe en la sección VGVar.handleOverflow; pero un cálculo aritmético no afecta a ninguna de las variables del sistema relacionadas con errores.

Las variables de sistema relacionadas con errores tampoco se ven afectadas por la invocación de una función que no sea una función de sistema, y sysVar.errorCode (la variable afectada por la mayoría de funciones de sistema) no se ve afectada por los errores en las siguientes funciones:
  • sysLib.calculateChkDigitMod10
  • sysLib.calculateChkDigitMod11
  • strLib.concatenate
  • strLib.concatenateWithSeparator
  • VGLib.concatenateBytes
  • VGLib.connectionService
  • sysLib.connect
  • sysLib.convert
  • sysLib.disconnect
  • sysLib.disconnectAll
  • sysLib.purge
  • sysLib.queryCurrentDatabase
  • strLib.setBlankTerminator
  • sysLib.setCurrentDatabase
  • strLib.strLen
  • sysLib.verifyChkDigitMod10
  • sysLib.verifyChkDigitMod11
  • sysLib.wait

El entorno de ejecución EGL no cambia el valor de ninguna variable relacionada con errores cuando las sentencias se ejecutan fuera de un bloque try. Sin embargo, el programa puede asignar un valor a una variable relacionada con errores fuera de un bloque try.

Sentencias de E/S

En relación con las sentencias de E/S, un error puede ser grave o leve:
  • Un error leve puede ser cualquiera de los siguientes:
    • No se ha encontrado ningún registro durante una operación de E/S en una tabla de base de datos SQL
    • Se produce uno de los siguientes problemas en una operación de E/S en un archivo indexado, relativo o serie, en un segmento DL/I o en otro acceso a DL/I:
      • Registro duplicado (cuando el almacén de datos externo permite insertar un duplicado). El código de estado DL/I equivalente es II.
      • No se ha encontrado ningún registro. El código de estado DL/I equivalente es GE y el código de estado de cola de mensajes de IMS es QD.
      • Fin de archivo. El código de estado DL/I o GSAM es GB y el código de estado de cola de mensajes de IMS equivalente es QC.
  • En la mayoría de casos, un error grave es cualquier otro problema, por ejemplo:
    • Registro duplicado (cuando el almacén de datos externo prohíbe insertar un duplicado)
    • No se ha encontrado un archivo
    • Los enlaces de comunicación no están disponibles durante el acceso remoto de un conjunto de datos

    Respecto a DL/I, un error grave es cualquier código de estado que no esté en blanco que no sea GA, GB, GD, GE, GK o II. Respecto a GSAM, un error grave es cualquier código que no esté en blanco y que no sea GB. Respecto a IMS, un error grave es cualquier código de estado que no esté en blanco y que no sea QC, QD, CE, CF, CG, CI, CJ, CK o CL.

Si la sentencia que causa el error leve está en un bloque try, se aplican las sentencias siguientes:
  • Por omisión, EGL continúa ejecutándose sin pasar el control al bloque onException
  • Si desea pasar el control al bloque OnException, establezca la propiedad throwNrfEofExceptions en yes en un programa, pageHandler o biblioteca
Si se produce un error grave de E/S en un bloque try, la consecuencia depende del valor de una variable de sistema relacionada con errores:
  • Durante el acceso de un archivo, base de datos relacional o cola de mensajes MQSeries, se aplican las siguientes normas:
    • Si sysVar.handleHardIOErrors se establece en 1, el programa continúa ejecutándose
    • Si sysVar.handleHardIOErrors se establece en 0, el programa presenta un mensaje de error, si es posible, y finaliza

    El valor por omisión de esa variable es dependiente del valor de la propiedad handleHardIOErrors , que está disponible en componentes de lógica generable como programas, bibliotecas y pageHandlers. El valor por omisión para la propiedad es yes, que establece el valor inicial de la variable sysVar.handleHardIOErrors en 1.

  • Durante el acceso de una cola IMS o base de datos DL/I, se aplican las siguientes normas:
    • Si VGVar.handleHardIOErrors o DLIVar.handleHardDLIErrors se establece en 1, el programa continúa ejecutándose
    • Si VGVar.handleHardIOErrors o DLIVar.handleHardDLIErrors se establece en 0, el programa presenta un mensaje de error, si es posible, y finaliza

Si se produce un error grave o leve de E/S fuera de un bloque try, el programa generado presenta un mensaje de error, si es posible, y finaliza.

Si accede a DB2 directamente (no a través de JDBC), el sqlcode para un error grave es 304, 802 o menor de 0.

Identificación de errores

Puede determinar qué tipo de error se ha producido en un bloque try incluyendo una sentencia case o if dentro o fuera del bloque try, y en esta sentencia puede probar el valor de diversas variables de sistema. Sin embargo, si responde a un error de E/S y si la sentencia utiliza un registro EGL, se recomienda utilizar una expresión lógica básica. Están disponibles dos formatos de la expresión:
  nombreRegistro es valorErrorES

  nombreRegistro no es valorErrorES
nombreRegistro
Nombre del registro utilizado en la operación de E/S
valorErrorES
Uno de varios valores de error de E/S que son constantes en diferentes sistemas de gestión de bases de datos

Si no utiliza las expresiones lógicas con valores de error de E/S y luego cambia los sistemas de gestión de base de datos, es posible que necesite modificar y volver a generar el programa. En particular, es aconsejable utilizar los valores de error de E/S para comprobar los errores en lugar del valor de sysVar.sqlcode o sysVar.sqlState. Dichos valores dependen de la implementación de base de datos subyacente.

Comentarios
(C) Copyright IBM Corporation 2000, 2005. Reservados todos los derechos.