2009-12-30 23 views
56

En un proyecto reciente, recomendé capturar una RuntimeException dentro de un código de arnés de prueba y registrarla. El código procesa una serie de entradas de una base de datos, y no quiero que la prueba se detenga debido a la falla de una entrada (valores nulos, argumentos ilegales, etc.). Huelga decir que mi sugerencia provocó una discusión apasionada.Cuándo está bien atrapar una RuntimeException

¿Es aceptable cualquier tipo de RuntimeException? En caso afirmativo, ¿cuáles son otros escenarios en los que está bien capturar RuntimeExceptions?

Respuesta

79

Capturas RuntimeException por la misma razón que capturas una excepción: planeas hacer algo con ella. Quizás puedas corregir lo que haya causado la excepción. Quizás simplemente desee volver a lanzar con un tipo de excepción diferente.

Catching y haciendo caso omiso de cualquier excepción, sin embargo, es una práctica extremadamente mala.

+19

O atrape el registro y vuelva a lanzar. –

+2

tiene perfecto sentido, debería haber vuelto a lo básico. Muchas veces los patrones se vuelven tan rígidos que los desarrolladores tienden a tomarlos como Dogma. Siempre me han dicho que RuntimeExceptions es el resultado de a) Errores de programación b) Fallas catastróficas de las que no se puede recuperar. En el caso (a), debe asegurarse de que todo esté arreglado antes de que el producto entre en funcionamiento y "nunca" ocurrirá. En cuanto al caso (b), el usuario debería ver que un mensaje más higienizado tiene mucho sentido capturar y procesar. Ahora me pregunto por qué necesitamos RuntimeExceptions, tal vez un tema para otra discusión ;-) – VDev

+1

Heh, creo que es más una razón para hacer que * todas * las excepciones sean excepciones de tiempo de ejecución. Hay muchos programadores que atraparán e ignorarán las excepciones marcadas, solo para que desaparezcan. – kdgregory

3

Personalmente, siempre me han dicho que quiere capturar todos RuntimeExceptions; sin embargo, también desea hacer algo sobre la excepción, como ejecutar un failsafe o posiblemente simplemente informar al usuario de que se produjo un error.

El último proyecto de Java en el que trabajé tenía un enfoque similar, al menos, registraríamos la excepción para que si un usuario llamaba quejándose de un error, pudiéramos averiguar exactamente qué sucedió y ver dónde ocurrió el error ocurrió.

Edición 1: Como dijo kdgregory, absorción y haciendo caso omiso son dos cosas diferentes, por lo general, las personas se oponen a este último :-)

14

RuntimeException está destinado a ser utilizado por los errores de programador. Como tal, nunca debería ser atrapado. Hay algunos casos donde debe estar:

  1. que está llamando código que viene de una tercera parte en la que no tiene control sobre cuando tiran una excepción. Argumentaría que debe hacer esto caso por caso y ajustar el uso del código de terceros dentro de sus propias clases para que pueda revertir excepciones que no sean de tiempo de ejecución.

  2. su programa no puede bloquearse y dejar un rastro de pila para que el usuario lo vea. En este caso, debería ir alrededor de los hilos principales y el código de manejo de eventos. El programa probablemente debería salir cuando tal excepción ocurra también.

En su caso específico que tendría que preguntarse por qué usted está teniendo RuntimeExceptions se producen en las pruebas - usted debe ser la fijación de ellos en lugar de trabajar alrededor de ellos.

Así que debe garantizar que su código solo arroja RuntimeExceptions cuando desea que el programa salga. Solo debe capturar RuntimeExceptions cuando quiera iniciar sesión y salir. Eso es lo que está en línea con la intención de RuntimeExceptions.

You can look at this discussion por otras razones que la gente da ... Personalmente, no he encontrado un motivo convincente en las respuestas.

+0

Creo que quiere decir "caso por caso" ... –

+0

errores tipográficos ... ¡vaya a lo grande o vaya a casa! ¡Gracias! – TofuBeer

+0

O 3. puede resolver o solucionar el problema en un nivel medio antes de que escape por el árbol de la pila – tar

6

En mi código, el 99% de mis excepciones se derivan de runtime_exception.

Las razones por las que capturar las excepciones son:

  • Catch registro y arreglar el problema.
  • captura de registro y generar una excepción más específica y tirar
  • Catch registro y volver a lanzar .
  • Catch registro y operación de Matar (a excepción de descarte) la acción
    • usuario/solicitud iniciada falla.
      Un controlador de solicitud HTTP, por ejemplo. Prefiero que la operación solicitada muera en lugar de anular el Servicio. (Aunque es preferible que el controlador tenga suficiente sentido para devolver un código de error 500).
    • Caso de prueba pasado/no aprobado con una excepción.
    • Todas las excepciones no están en el hilo principal.
      Permitir que las excepciones escapen un subproceso generalmente está mal documentado, pero generalmente causa la terminación del programa (sin desenrollar la pila).
28

menos que se puede corregir una RuntimeException, que no quiere cogerlo ...

... sólo es cierto desde un punto de vista desarrolladores ....

tiene que detectar todas las excepciones antes de que lleguen a la IU y hacer que su usuario triste. Esto significa que en el "nivel más alto" desea capturar cualquier cosa que ocurra más abajo. Luego puede informar al usuario que hubo un problema y al mismo tiempo tomar medidas para informar a los desarrolladores, como enviar correos de alarma o lo que sea ...

Básicamente se considera un error de datos/programación que no se pudo previsto, por lo tanto, desea mejorar las versiones futuras del software mientras que al mismo tiempo toma al usuario de la mano y avanza de forma controlada ...

2

Usted detecta RuntimeException cuando desea procesarlo. Quizás desee volver a lanzarlo como una excepción diferente o registrarlo en un archivo o base de datos, o si desea activar alguna bandera de excepción en el tipo de devolución, etc.

1

Captura RuntimeExceptions (en cualquier idioma: excepciones inesperadas/"Todas" excepciones) cuando su programa está haciendo subtareas múltiples y tiene sentido completar todas las que pueda en lugar de detenerse en la primera situación inesperada. Un conjunto de pruebas es una buena situación para hacer esto: desea saber cuál de todas las pruebas fallaron, no solo la primera prueba. La característica clave es que cada prueba es independiente de todas las demás; no importa si una prueba previa no se ejecuta porque la orden no es significativa de todos modos.

Otra situación común es un servidor; no quiere cerrar solo porque una solicitud fue malformada de una manera que no esperaba. (A menos que sea realmente importante minimizar las posibilidades de un estado incoherente).

En cualquiera de estas situaciones, lo apropiado es registrar/informar la excepción y continuar con las tareas restantes.

Se podría vagamente generalizar a cualquier excepción: es “adecuada para atrapar” una excepción si y sólo si hay algo sensato después de la captura de él: cómo el programa debe continuar. Hace

7

años, escribimos un marco de sistema de control y los objetos atrapados Agente excepciones de tiempo de ejecución, que registra si podían y continua.

Sí nos atrapado tiempo de ejecución excepciones incluyendo OutOfMemory en nuestro código de la arquitectura (y obligado a un GC, y es sorprendente lo bien que mantienen código de ejecución incluso bastante permeable.) Tuvimos código que estaba haciendo cosas muy matemáticos que implican el verdadero mundo; y de vez en cuando, un Not-A-Number entraba debido a pequeños errores de redondeo y también lo solucionaba bien.

Así, en el marco/"no debe salir" código creo que puede ser justificable. Y cuando funciona, es genial.

El código era bastante sólido, pero corrió el hardware y el hardware tiende a dar respuestas screwy veces.

que fue diseñado para funcionar sin intervención humana durante meses a la vez. Funcionó extremadamente bien en nuestras pruebas.

Como parte del código de recuperación de errores, se podría recurrir a reiniciar todo el edificio utilizando la capacidad del UPS para que se apague en N minutos y encienda en M minutos.

veces fallos de hardware necesario apagar y encender :)

Si mal no recuerdo, el último recurso después de un ciclo de encendido sin éxito era que el envío de un correo electrónico a sus propietarios, diciendo "Traté de prepararme y puedo' t; el problema está en el subsistema XYZ ", e incluyó un enlace para enviarnos una llamada de soporte.

Por desgracia, el proyecto se puso en lata antes de que pudiera llegar a ser consciente de sí mismo:)>

+3

OutOfMemoryError es un error, no una excepción – Demi

+0

más uno por mencionar 'autoconsciente' ... solo si fuera el 4 de agosto de 1997 . – shrini1000

3

todos sabemos que las excepciones comprobadas y RuntimeExceptions son las dos categorías de excepciones. Siempre se sugiere que manejemos (ya sea try-catch o throw) las excepciones comprobadas porque son las condiciones de programación donde desafortunadamente el programador no puede hacer nada por sí mismo; Como FileNotFoundException no es el programador que pone los archivos en la unidad del usuario si el programa es en realidad tratando de leer el archivo 1.txt que se supone que es allí en f:\ del usuario con las declaraciones:

File f11 = new File("f:\\1.txt"); 
FileInputStream fos = new FileInputStream(f11); 

Si no se encuentra el archivo todo está bien, pero lo que sucede en el otro caso, si el archivo no se encuentra, es que el programa se bloquea con 0 error del usuario. En este escenario, el programador no hizo nada incorrecto. Esta podría ser una excepción comprobada que debe capturarse para que el programa continúe ejecutándose.

también quisiera explicar el segundo escenario con el que el concepto de RuntimeException será clara. Considere siguiente código:

int a = {1,2,3,4,5}; 
System.out.println(a[9]); 

Esta es pobre codificación que genera el ArrayIndexOutOfBoundsException. Que es un ejemplo de RuntimeException. Por lo tanto, el programador no debería manejar la excepción, dejar que bloquee el programa y luego arreglar la lógica.

0

Si se puede esperar razonablemente que un cliente se recupere de una excepción, conviértalo en una excepción marcada.

Si un cliente no puede hacer nada para recuperarse de la excepción, conviértalo en una excepción no verificada.

Aquí está la pauta de la línea inferior.

De Java Docs. Lea esto Unchecked Exceptions — The Controversy

Cuestiones relacionadas