iberck
6/7/2016 - 3:25 PM

Excepciones

Excepciones

¿Retornar código de error o lanzar excepción?

Todo depende de la naturaleza del problema, la regla es programar lo que sea más natural e intuitivo dentro del código.

Por regla general se deben retornar códigos de error cuando el retorno sea algo NATURAL (esperado) dentro de la lógica del proceso y se deben lanzar excepciones cuando suceda algo EXCEPCIONAL (no esperado) dentro de la lógica del proceso. La excepción debe ser lanzada cuando la operación no pueda ser completada como se solicitó, es decir cuando suceda algo EXCEPCIONAL dentro del flujo normal del proceso.

Por ejemplo, si se crea un usuario debería lanzar una excepción si no lo puede crear en la base de datos (sucede una excepción no esperada, es decir algo excepcional), pero se debería retornar un código de error si por ejemplo el nombre del usuario está repetido.

Control de flujo basado en excepciones

Se considera una mala práctica tomar decisiones basándose en las excepciones ya que rompe con el flujo natural del programa, no es lo mismo leer if condición then A else B que try A catch then B

  • Es considerado un antipatrón
  • El código se vuelve poco legible, dificil de leer, difícil de analizar, dependiente del lenguaje.
  • Es una manera costosa de tomar decisiones (50 veces más lento)
  • Las excepciones no fueron diseñadas para tomar decisiones, fueron diseñadas para notificar condiciones anormales dentro del flujo natural del programa.
  • Las decisiones deben ser tomadas con las sentencias if/else, switch

Un código de error es conveniente retornarlo cuando el cliente del método toma decisiones en base al resultado, de esta forma se podrá validar el resultado con sentencias if/else switch en vez de con sentencias try/catch.

Por ejemplo, se tiene el método searchUser para validar si existe un usuario. En este caso conviene que searchUser retorne null (por ejemplo) para indicar que no existe el usuario y se pueda validar que si searchUser retorna null se realicen otras acciones. Si no se fuera a tomar decisiones en base a la existencia del usuario y la app esperara que siempre existieran los usuarios, entonces sería más natural lanzar excepciones indicando que sucedió algo excepcional porque siempre debería existir el usuario.

Excepciones en webservices, ¿retornar códigos o lanzar faults?

Cuando ocurre una excepción en un webservice, ¿se debe lanzar una excepción o retornar un código de error?

Siempre que suceda algo inesperado dentro del flujo normal del programa, por ejemplo un error de invocación, se recomienda lanzar una excepción (soap fault)

Sin embargo, cuando el cliente el ws es un cliente limitado o simplemente es el requerimiento, entonces es cuando se deben retornar códigos de error.

Ejemplos

Ejemplos de retorno: Validar si existe un usuario dentro de la aplicación (retornar true o false)

Ejemplos excepciones: Ejemplo de excepción: No se puede realizar la conexión a la bd porque está caida.

Tipos de excepciones

Errores

Son las excepciones fatales y no es posible hacer nada al respecto, por ejemplo se terminó la memoria. Los errores no son excepciones checadas ya que cuando son lanzados se supone que no hay nada más que hacer.

Excepciones cachadas extends Exception

Este tipo de excepciones se utilizan típicamente cuando es MUY IMPORTANTE notificarlas al programador para que las tome en cuenta porque se piensa que puede recuperarse realizando alguna acción. Por ejemplo si no se puede mover un archivo, el usuario se podría recuperar haciendo únicamente la copia del mismo.

Típicamente no son problemas de programación, por ejemplo un error de conexión, no se puede leer/escribir un archivo, un error de seguridad.

Excepciones no cachadas extends RuntimeException

Típicamente son errores de programación, por ejemplo un valor es nulo, una división entre 0, un argumento incorrecto, una regex mal construida. A diferencia de las excepciones cheched (cachadas), las runtimeexceptions no obligan a poner try/catch y eso ayuda a hacer el código más simple y más legible.

En este tipo de excepciones solo debes usar try/catch si deseas hacer algo al respecto, por lo tanto se recomienda poner y documentar las excepciones que lanza cada método.

Recomendaciones y práctica

Effective java (Joshua Bloch):

Utiliza checked exceptions para una condición recuperable y runtimeexceptions para errores de programación.

Los lenguajes/frameworks que utilizan unchecked exceptions son: Groovy, ceylon, spring, hibernate, groovy, c#.

En la práctica, con los años se ha demostrado que no tiene mucho sentido utilizar excepciones cachadas, ya que en la mayoría de los casos el código que manda la excepción no puede hacer nada con ella y solo deja que suba en la cadena de llamado.

Lanzar Exception y cachar Throwable

Ambos son malas prácticas, lanzar Exception es como retornar Object.

Cachar Throwable hace que también se cachen los Errores, los cuales no deberían ser cachados para dejar que termine el programa ya que algo fatal sucedió.