Excepciones
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.
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
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.
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 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.
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.
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.
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.
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.
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ó.