viernes, 3 de octubre de 2008

Errores y excepciones (III)

Errores y excepciones (I)

Errores y excepciones (II)

Errores y excepciones (III)

El manejo de errores y excepciones fue una de las cuestiones que más me costó aprender en mi vida profesional.

Aunque parezca un sin sentido, me ayudó bastante empezar con Visual Basic, en la época en que todavía no tenía un manejo estructurado de excepciones, que recién fue incorporado en la versión 6 (creo).

En aquellos tiempos poco le importaban a mi jefe (como a todos, creo) las cuestiones metodológicas, la prolijidad del código, la arquitectura o el devaneo filosófico alrededor del desarrollo de software... y la verdad que a mí tampoco, solamente me divertía escribir código, cosa que hacía muy poco profesionalmente, era más bien un juego por el que me pagaban.

Cuestión que en mi primera aplicación de escritorio y luego de un par de pruebas, la consigna era que el sistema no se tiene que cerrar jamás a causa de un error (cosa que ni se me había cruzado por la cabeza). Sin pensarlo dos veces, metí manos a la obra.

Pasé por la etapa del On error resume next. Es fácil darse cuenta de que no sirve para nada. Al fin y al cabo, si una función o procedimiento no daba error, probablemente lo daría el que lo llamó. Además ocasionaba comportamientos extremadamente impredecibles, por decir lo menos. La aplicación se cerraba menos, pero funcionaba peor y lo más divertido de todo era depurarla...

Luego tuve mi etapa de a prueba de balas, en el que trataba, en cada procedimiento, de pensar qué haría ante un fallo o respuesta inesperada de cualquiera de los procedimientos a los que llamaba. Esto genera código imposible: contemplaba en cada llamada una cantidad de respuestas y situaciones que nunca ocurrirían, llenando todo de código que nunca se ejecutaría. Usualmente lo que daba error era el código que hacía esas comprobaciones. Es extremadamente difícil y bastante inútil. ¿Cómo podemos pensar qué haríamos ante un error del que no tenemos ninguna información?

Así que después de un par de tortazos (pruebas y errores, muchos errores) me dí cuenta de que solamente tenía que controlar los errores de programación en un sólo lugar: trabajaba con Visual 5 en una aplicación de escritorio, así que éste tipo de errores hacían "explotar" a la aplicación sólo en un punto: en el código que maneja los eventos en los formularios. Cualquier error burbujea hasta el manejador del evento que recibe el comando del usuario y ahí explota, cerrando la aplicación.

Así que me dediqué a poner On error goto MensajeError, un Exit Sub y luego la etiqueta MensajeError, que llamaba a una función que mostraba los datos del error y listo. El código era bastante feo.

Como no me gustaba tener código impredecible o código inútil, borré cualquier manejo de error que no sea el mencionado. Y todo anduvo de perillas.

Pero con más pruebas surgieron problemas: algunos errores se daban en momentos poco oportunos, dejando archivos abiertos, operaciones por la mitad y un sinfín de basura y cosas a medio hacer. Y aparte se mostraban errores catastróficos por algunas tonterías: falta de validaciones de los datos ingresados por el usuario, sobre todo.

Así que de vuelta empecé a poner manejo de errores más allá de los manejadores de eventos, para "limpiar" eventuales desastres.

Pero me di cuenta de que los mensajes son importantes: como usuarios, imaginen que después de ingresar 20 datos en una pantalla el sistema les dice Duplicated primary key o algo por el estilo. Un programador puede decir "ya ingresaste ese código de producto", pero para el usuario el sistema no funciona, y no entiende por qué. Mi única solución para el caso era corregir la falta de validación, arreglando la omisión de programación que se veía tan fea.

Cuando comencé a utilizar lenguajes orientados a objetos y manejo estructurado de errores (Exception en el código), sobre todo en C# reproduje la misma estructura de control de errores.

Y luego, recién después de un tiempo más, aprendí a usar excepciones en una forma más genérica y no pura y exclusivamente para el manejo de errores de codificación.

Todo ese recorrido me hizo llegar al manejo de bloques try...catch...finally sabiendo (por lo menos en una mínima parte) para qué servían. Y eso fue fundamental. Porque (esto lo veo en programadores junior y también en alumnos) que entender conceptualmente qué es un error, qué es una excepción y qué hacer con ello, es muy duro. Aún con mejores herramientas, creo que todos transitarán un camino parecido al mío (salvo que utilicen intensivamente una que yo no tuve al principio: internet).

Creo que éstos tres artículos fueron un pasable resumen, que tal vez con un poco más de tiempo pueda emprolijar y complementar con más ejemplos. Sugerencias, como siempre, más que bienvenidas.

2 comentarios:

Anónimo dijo...

Muy buen repaso, disfrute leyendo las tres partes, a las que encontré bien explicadas, concisas y clarificadoras.

Saludos y gracias por el material

Anónimo dijo...

Muy buen articulo..