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 de EGL

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:
    • Se produce una anomalía en la invocación o retorno de una función escrita por el usuario;
    • Se asigna un carácter no numérico a una variable numérica; o bien
    • La variable de sistema VGVar.handleHardIOErrors se establece en cero en lugar de en uno cuando una sentencia de E/S de archivo finaliza con un error grave (como se describe más adelante).
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
Nota: 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.

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.

En algunas situaciones se asigna un valor a la variable de sistema sysVar.exceptionCode y en todas estas situaciones también se establece una o más variables adicionales, en función de la naturaleza de la interacción del programa con el entorno de ejecución:
  • Se asignan valores a las variables de sistema sysVar.exceptionCode y sysVar.errorCode después de que se ejecute alguno de los siguientes tipos de sentencias en un bloque try:
    • 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
  • Se asignan valores a las variables del sistema sysVar.exceptionCode, sysVar.errorCode, VGVar.mqConditionCode y sysVar.mqReasonCode después de que una sentencia de E/S de un bloque try actúe sobre un registro MQ
  • La variable de sistema sysVar.exceptionCode recibe un valor una vez que se ha accedido a una base de datos relacional desde una sentencia de un bloque try. También se asignan valores a variables del área de comunicación SQL (SQLCA); para obtener detalles, consulte sysVar.sqlca.

Si se produce un error de no terminación en un bloque try, el valor de sysVar.exceptionCode es equivalente al componente numérico del mensaje de error EGL que se presentaría al usuario si el error se produjese fuera del bloque try. Sin embargo, el sistema de ejecución proporciona los valores de las variables específicas de la situación, como por ejemplo sysVar.errorCode y VGVar.mqConditionCode. En ausencia de un error, el valor de sysVar.exceptionCode y de al menos una de las variables específicas de la situación es el mismo: una serie de ocho ceros.

Se asigna un código de error a sysVar.exceptionCode y 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 satisfactorio no afecta a ninguna de las variables de 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.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

Cuando se asigna un valor de error a sysVar.exceptionCode, a la variable de sistema sysVar.exceptionMsg se le asigna el texto del mensaje de error EGL relacionado y a la variable de sistema sysVar.exceptionMsgCount se le asigna el número de bytes del mensaje de error, excluidos los nulos y blancos finales. Cuando se asigna una serie de ocho ceros a sysVar.exceptionCode, se asignan blancos a sysVar.exceptionMsg y sysVar.exceptionMsgCount se establece en cero.

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
    • Se produce uno de los siguientes problemas en una operación de E/S en un archivo indexado, relativo o serie:
      • Registro duplicado (cuando el almacén de datos externo permite insertar un duplicado)
      • No se ha encontrado ningún registro
      • Fin de archivo
  • Un error grave puede ser cualquier otro problema, como 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
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 VGVar.handleHardIOErrors se establece en 1, el programa continúa ejecutándose
    • Si VGVar.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 VGVar.handleHardIOErrors en 1.

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.

Condiciones de uso | Comentarios
(C) Copyright IBM Corporation 2000, 2005. Reservados todos los derechos.