¿Es una mala práctica atrapar Throwable
?
Por ejemplo, algo como esto:
try {
// Some code
} catch(Throwable e) {
// handle the exception
}
¿Es esta una mala práctica o deberíamos ser lo más específicos posible?
java
exception-handling
throwable
ktulinho
fuente
fuente
Respuestas:
Debe ser lo más específico posible. De lo contrario, los errores imprevistos podrían desaparecer de esta manera.
Además, también
Throwable
cubreError
y eso no suele ser un punto de retorno . No quiere captar / manejar eso, quiere que su programa muera inmediatamente para que pueda solucionarlo correctamente.fuente
Esta es una mala idea. De hecho, incluso atrapar
Exception
suele ser una mala idea. Consideremos un ejemplo:Ahora, digamos que getUserInput () se bloquea por un tiempo, y otro hilo detiene su hilo de la peor manera posible (llama thread.stop ()). Su bloque de captura detectará un
ThreadDeath
error. Esto es muy malo. El comportamiento de su código después de detectar esa excepción es en gran parte indefinido.Se produce un problema similar al detectar la excepción. Tal vez
getUserInput()
falló debido a una InterruptException, o una excepción de permiso denegado al intentar registrar los resultados, o todo tipo de otras fallas. No tiene idea de qué salió mal, ya que debido a eso, tampoco tiene idea de cómo solucionar el problema.Tienes tres opciones mejores:
1 - Detecte exactamente las excepciones que sabe cómo manejar:
2 - Vuelva a lanzar cualquier excepción con la que se encuentre y no sepa cómo manejar:
3 - Use un bloque de finalmente para que no tenga que acordarse de volver a lanzar:
fuente
throw new Exception("Some additional info, eg. userId " + userId, e);
. Esto se registrará en una buena excepción con 10 causas.También tenga en cuenta que cuando lo atrape
Throwable
, también puede atrapar, loInterruptedException
que requiere un tratamiento especial. Consulte Manejo de InterruptedException para obtener más detalles.Si solo desea detectar excepciones no marcadas, también puede considerar este patrón
De esta manera, cuando modifica su código y agrega una llamada a un método que puede generar una excepción marcada, el compilador se lo recordará y luego podrá decidir qué hacer en este caso.
fuente
directamente del javadoc de la clase Error (que recomienda no atraparlos):
fuente
No es una mala práctica si absolutamente no puede tener una burbuja de excepción de un método.
Es una mala práctica si realmente no puede manejar la excepción. Es mejor agregar "lanzamientos" a la firma del método que simplemente capturar y volver a lanzar o, peor aún, envolverlo en una RuntimeException y volver a lanzarlo.
fuente
Throwable
instancias, por ejemplo, para el registro de excepciones personalizado.La captura de Throwable a veces es necesaria si está utilizando bibliotecas que arrojan Errores con demasiado entusiasmo, de lo contrario, su biblioteca puede matar su aplicación.
Sin embargo, sería mejor en estas circunstancias especificar solo los errores específicos lanzados por la biblioteca, en lugar de todos los Throwables.
fuente
Throwable es la clase base para todas las clases que se pueden lanzar (no solo excepciones). Es poco lo que puede hacer si detecta un OutOfMemoryError o KernelError (consulte ¿ Cuándo detectar java.lang.Error? )
la captura de Excepciones debería ser suficiente.
fuente
depende de su lógica o de ser más específico a sus opciones / posibilidades. Si hay alguna excepción específica sobre la que posiblemente pueda reaccionar de una manera significativa, puede detectarla primero y hacerlo.
Si no lo hay y está seguro de que hará lo mismo para todas las excepciones y errores (por ejemplo, salir con un mensaje de error), entonces no es un problema atrapar el lanzador.
Por lo general, el primer caso se sostiene y no atraparías el lanzador. Pero todavía hay muchos casos en los que detectarlo funciona bien.
fuente
Aunque se describe como una práctica muy mala, a veces puede encontrar casos raros que no solo son útiles sino también obligatorios. A continuación se muestran dos ejemplos.
En una aplicación web en la que debe mostrar al usuario una página de error completa con significado. Este código se asegura de que esto suceda, ya que es importante para
try/catch
todos los manejadores de solicitudes (servlets, acciones de struts o cualquier controlador ...)}
Como otro ejemplo, considere que tiene una clase de servicio que sirve para negocios de transferencia de fondos. Este método devuelve
TransferReceipt
si se realiza la transferencia oNULL
si no se pudo.Ahora la imagen obtiene una cantidad
List
de transferencias de fondos del usuario y debe usar el servicio anterior para hacerlas todas.Pero, ¿qué pasará si ocurre alguna excepción? No debe detenerse, ya que una transferencia puede haber sido exitosa y otra no, debe continuar con todos los usuarios
List
y mostrar el resultado a cada transferencia. Entonces terminas con este código.Puede explorar muchos proyectos de código abierto para ver que
throwable
realmente se almacena en caché y se maneja. Por ejemplo, aquí es una búsqueda detomcat
,struts2
yprimefaces
:https://github.com/apache/tomcat/search?utf8=%E2%9C%93&q=catch%28Throwable https://github.com/apache/struts/search?utf8=%E2%9C%93&q=catch % 28Throwable https://github.com/primefaces/primefaces/search?utf8=%E2%9C%93&q=catch%28Throwable
fuente
throwable
, de eso se trata esta preguntaLa pregunta es un poco vaga; ¿Estás preguntando "está bien atrapar
Throwable
" o "está bien atrapar unThrowable
y no hacer nada"? Mucha gente aquí respondió lo último, pero ese es un tema secundario; El 99% de las veces no se debería "consumir" o descartar la excepción, si tienes que cogerThrowable
oIOException
lo que sea.Si propaga la excepción, la respuesta (como la respuesta a tantas preguntas) es "depende". Depende de lo que esté haciendo con la excepción: por qué lo está contagiando.
Un buen ejemplo de por qué querría capturar
Throwable
es proporcionar algún tipo de limpieza si hay algún error. Por ejemplo, en JDBC, si ocurre un error durante una transacción, querrá revertir la transacción:Tenga en cuenta que la excepción no se descarta, sino que se propaga.
Pero como política general, detectar
Throwable
porque no tiene una razón y es demasiado vago para ver qué excepciones específicas se están lanzando es una mala idea y una mala idea.fuente
En términos generales, desea evitar la captura de mensajes de correo
Error
electrónico, pero puedo pensar en (al menos) dos casos específicos en los que es apropiado hacerlo:AssertionError
si son inofensivos.fuente
Si usamos throwable , entonces también cubre Error y eso es todo.
Ejemplo.
}
Salida:
fuente
Throwable es la superclase de todos los errores y excesos. Si usa Throwable en una cláusula catch, no solo detectará todas las excepciones, sino que también detectará todos los errores. La JVM genera errores para indicar problemas graves que no están destinados a ser manejados por una aplicación. Ejemplos típicos de eso son OutOfMemoryError o StackOverflowError. Ambos son causados por situaciones que están fuera del control de la aplicación y no se pueden manejar. Por lo tanto, no debe capturar Throwables a menos que esté bastante seguro de que solo será una excepción dentro de Throwable.
fuente
Si bien en general es una mala práctica atrapar Throwable (como se aclara por las numerosas respuestas a esta pregunta), los escenarios en los que atrapar
Throwable
es útil son bastante comunes. Permítanme explicarles uno de esos casos que utilizo en mi trabajo, con un ejemplo simplificado.Considere un método que realiza la suma de dos números y, después de la suma exitosa, envía una alerta por correo electrónico a ciertas personas. Suponga que el número devuelto es importante y lo utiliza el método de llamada.
El código para enviar alertas por correo electrónico lee muchas configuraciones del sistema y, por lo tanto, podría haber una variedad de excepciones lanzadas desde ese bloque de código. Pero no queremos que ninguna excepción encontrada durante el envío de alertas se propague al método de la persona que llama, ya que ese método simplemente se ocupa de la suma de los dos valores enteros que proporciona. Por lo tanto, el código para enviar alertas por correo electrónico se coloca en un
try-catch
bloque, dondeThrowable
se captura y las excepciones simplemente se registran, lo que permite que continúe el resto del flujo.fuente
Exception
s por todos los medios, pero noThrowable
.