El arte perdido del manejo de Errores

Todos aquellos que desarrollamos aplicaciones que son utilizadas en ambientes productivos convivimos con el siguiente hecho: tarde o temprano tu código será ejecutado y producirá un mensaje de error (y posiblemente una falla). Algunas veces es esperado que suceda, otras no.
canedo_f7d8fb8700084443b4a6fe6d2771377e.png

Por @GerardoMCanedo 

 

Entender qué fue lo que sucedió, y obtener la suficiente información para poder tomar acciones (que eventualmente pueden incluir recodificar), no es una tarea trivial. Al contrario, las normales restricciones de acceso a los ambientes de producción hacen que la resolución del problema sea una tarea imposible, si no consideramos recopilar información y gestionar los posibles errores de forma adecuada.

Además, no todo es código fuente. Un programa depende del ambiente en el que se ejecuta, también generando errores. éstos pueden ser entradas de datos inválidas, archivos inexistentes, permisos insuficientes, discos llenos, configuraciones incorrectas del software, entre otros.

No importa lo “bien” que programemos, tenemos que convivir con estos casos en los cuales las cosas no irán como quisiéramos, y los tendremos que gestionar. Siempre es mejor gestionar estos errores que continuar con el flujo normal, lo que generalmente lleva a problemas de inconsistencia de datos (campos vacíos), u otros comportamientos que nos darán dolores de cabeza en la ejecución del sistema.

Éstos son algunos consejos que pueden ser de utilidad para el desarrollador GeneXus a la hora de gestionar errores:

1 – Validar códigos de error de funciones GeneXus

Varias funciones GeneXus retornan códigos de error al ser invocadas. Luego de utilizarlas, siempre debemos consultar el código de Error.

GERARDO 1

Encontrar una de las siguientes funciones sin un IF validando su código de error, es un potencial riesgo:

DFRClose DFRGDate() DFRGNum
DFRGTxt DFRNext DFROpen
DFWClose DFWPDate DFWPNum
DFWNext DFWOpen DFWPTxt
OpenDocument PrintDocument SetCookie
SetLanguage SetTheme SetUserId
SetWrkSt Shell WriteRegKey

2 – Web Services

Algo que puedo asegurar es que en producción, en algún momento, la invocación a un Web Service fallará. Los motivos pueden ser variados (red, el sistema que se encuentra del otro lado de la invocación, datos, formatos que se modificaron y no fueron actualizados, entre otros).

Si no gestionamos el error, nuestro usuario final verá un error en nuestro sistema, algo poco amigable que contribuye a la pérdida de confianza en el sistema. Peor aún, podemos finalizar con datos inconsistentes u otros problemas como conexiones abiertas. Incluso puede suceder que el otro sistema arrastre a nuestro sistema a un estado de error, magnificando el problema. Es imperativo tomar en cuenta estos casos a la hora de programar.

El manejo de errores de web services se hace a través del objeto Location, en particular de la propiedad CancelOnError. Si a esta propiedad se le asigna el valor 2, es posible utilizar las funciones GetSOAPErr y GetSOAPErrMsg.

El código para el consumo de un Web Service, tomando en cuenta los posibles errores, luce de la siguiente forma:

GERARDO 2

3 – Gestión de Errores en Procedimientos

Cuando nos encontramos escribiendo la lógica de negocios, normalmente utilizamos un conjunto de procedimientos. Muchas cosas pueden salir mal: falta de parametrización, errores propios de la lógica de negocio, los errores descriptos anteriormente, etc.

Una buena práctica de desarrollo es indicar en un parámetro el resultado de la operación. Este parámetro es un SDT en el que se indica un código de error, un mensaje y el resultado de la operación.

Este resultado de error de la operación debe ser devuelto hasta la frontera del sistema (Web Panel o servicio) como resultado de la propia operación. Gestionar los errores de esta forma también ayuda a programar de forma correcta las UTLs.

Rules

GERARDO3

SDT

gerardo 4

  • Success: true si la operación tuvo éxito, false en caso contrario. Es intencional que el éxito de la operación sea representado por el valor true. Esto para evitar que el resultado sea positivo por omisión, favoreciendo el principio de seguridad de seguridad por defecto.
  • Detalle: agrupa un código de error, una descripción (¡Amigable!) y eventualmente un tipo (error o advertencia). Una buena práctica de desarrollo es indicar un código único en toda la base de conocimiento para el error. De esta forma podemos utilizar la funcionalidad de Búsqueda de la IDE de GeneXus para determinar rápidamente el origen del error que eventualmente nos reporten.

Ejemplo de Uso

gerardo 5

Conclusiones

Los errores son inevitables y deben ser gestionados. Cualquiera de ellos que no sea tomado en cuenta a la hora de desarrollar puede terminar en una falla en producción, generando un impacto.  Es importante tenerlos en cuenta a la hora de codificar, no enmascararlos y generar la suficiente información para poder ser analizados una vez que ocurran.

 

Escrito por Gerardo Canedo, Gerente de Seguridad de GeneXus Consulting.

 

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión /  Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión /  Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión /  Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión /  Cambiar )

Conectando a %s