Antipatrones en el trabajo con excepciones (I)

Uno de los puntos en los que más fallan los desarrolladores noveles es a la hora de trabajar con excepciones. Existen numerosas formas de trabajar mal con excepciones.


También es curioso como muchos arquitectos a la hora de plantear un marco general de


manejo de excepciones para la aplicación caen, una y otra vez, en los mismo errores.


Cómo, desde un punto de vista general, la aplicación responde a las excepciones, en


que ocasiones estas se propagan hasta el usuario en forma de mensajes de error, cómo se responde a las excepciones totalmente inesperadas, o como se logea el comportamiento de la aplicación en lo que a manejo de excepciones se refiere, es algo, que a menudo no esta bien resuelto, a pesar de ser un punto de suma importancia desde el punto de vista arquitectónico. Debemos prestar atención, como arquitectos y como desarrolladores, a este tema, puesto que tiene una incidencia enorme en la mantenibilidad y manejabilidad de la aplicación una vez desplegada. Sin una buena política de manejo de excepciones, se hará sumamente difícil encontrar los errores que presente nuestra aplicación. Por eso voy a dedicar una serie de entradas en este blog al tema del uso correcto de excepciones.


 


Overthrowing: Número excesivo de excepciones.


 


Es habitual y recomendable lanzar una excepción cuando una función falla. También es


habitual que en la mayoría de las ocasiones la funciones hagan su labor correctamente de manera que, el que respondan con una excepción, es algo que no ocurre muy  a menudo. Pero en ocasiones ocurre que, nuestro código provoca que se lancen numerosas excepciones. Las excepciones son costosas en tiempo de ejecución, debido más que nada a que cada vez que se lanza una excepción se debe recorrer la pila de llamadas en dos ocasiones.


 


Un ejemplo de esta situación, bastante habitual, ocurre cuando necesitamos realizar una conversión desde una cadena, leída desde un archivo, a un valor numérico. Supongamos un archivo que contiene gran cantidad de cadenas, unas representan un numero y otras no. Supongamos que deseamos tratar las cadenas numéricas en variables enteras y descartar aquellas líneas que no sean enteras. Si la cadena, leída del archivo, esta contenida en la variable de tipo string s, parece lógico tener código como el siguiente:


 


try


{


i = int.Parse(s);


}


catch (FormatException)


{


//La conversión fallo, descartamos la cadena leída


//porque no es un entero


}


 


En principio no hay problema con este código, pero supongamos que un gran porcentaje de las cadenas que leemos del archivo no son numéricas. Esto provocará que se produzcan un gran numero de excepciones lo que penalizará en gran medida el rendimiento de nuestra aplicación. Unai ya trato este tema desde el punto de vista del rendimiento.


 


¿Qué solución tenemos a este problema? La verdad en que en el framework 1.1 no hay una buena solución. En la versión 2.0 del framework, se han añadido métodos que permiten comprobar esa situación sin recibir una excepción. Estos métodos siguen el patrón de en lugar de lanzar una excepción devolver un valor booleano que nos informa del resultado de la excepción sin pagar el precio en tiempo de ejecución de la excepción.


 


if (int.TryParse(i, s))


{


//s contiene un valor entero


}


else


{


//s no es un valor entero


}


 


La moraleja es clara, cuando queramos utilizar un método que lanza una excepción y preveemos que esta se produzca en muchas ocasiones, debemos buscar una manera alternativa de hacer las cosas que no implique que se produzcan numerosas excepciones. Y cuando implementemos un método que lanza excepciones y que preveeamos que puede ser llamado en escenarios que produzcan numerosas excepciones, debemos proveer un método alternativo que permita realizar la misma operación sin recibir excepciones. Implementar este segundo mecanismo unicamente no es una buena solución, las situaciones excepcionales deben comunicarse usando excepciones, no valores de retorno, esta es la norma general y solo debe implementarse un mecanismo alternativo si preveemos escenarios de uso de nuestro método en los que se vayan a producir un número excesivo de excepciones.


 


En la siguiente entrega: Overcatching: Recoger más tipos de excepción que los que nos incumben.

2 comentarios sobre “Antipatrones en el trabajo con excepciones (I)”

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *