practices practice handling hackerrank good exceptions custom catch best all java exception-handling

java - practice - Cuándo está bien atrapar una RuntimeException



java exception hierarchy (10)

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.

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


A menos que pueda corregir una RuntimeException, no quiere atraparla ...

... solo es cierto desde el punto de vista de los desarrolladores ...

tiene que atrapar todas las excepciones antes de que lleguen a la interfaz de usuario y entristezcan a su usuario . 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 podía prever, por lo que desea mejorar las versiones futuras del software mientras que al mismo tiempo toma al usuario de la mano y lo hace de forma controlada ...


Capturas RuntimeExceptions (en cualquier idioma: excepciones inesperadas / "todas" excepciones) cuando tu programa está haciendo subtareas múltiples y tiene sentido completar todas las que puedas en lugar de detenerte en la primera situación inesperada. Un conjunto de pruebas es una buena opción para hacer esto: desea saber cuál de todas las pruebas falló, no solo la primera. 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.

Uno podría generalizar vagamente a cualquier excepción: es "apropiado atrapar" una excepción si y solo si hay algo sensato que hacer después de atraparlo: cómo debe continuar su programa .


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

Las razones por las que capté excepciones son:

  • Catch Log and Fix problema.
  • Capturar registro y generar una excepción más específica y lanzar
  • Catch Log y Rethrow .
  • Catch Log and Kill operation (excepción de descarte)
    • La acción iniciada por el usuario / solicitud falla.
      Un manejador de solicitudes HTTP, por ejemplo. Prefiero que la operación solicitada muera en lugar de anular el Servicio. (Aunque preferiblemente el manejador tiene suficiente sentido para devolver un código de error 500).
    • El caso de prueba pasó / falló con una excepción.
    • Todas las excepciones no están en el hilo principal.
      Permitir excepciones para escapar de un hilo generalmente está mal documentado, pero generalmente causa la terminación del programa (sin desenrollar la pila).

Hace años, escribimos un marco de sistema de control y los objetos del Agente capturaron las excepciones de tiempo de ejecución, las registraron si podían y continuaron.

Sí, detectamos excepciones de Runtime, incluido OutOfMemory en nuestro código de framework (y forzamos un GC, y es sorprendente lo bien que eso mantuvo incluso funcionando un código bastante defectuoso). Tuvimos código que estaba haciendo cosas muy matemáticas que involucraban el mundo real; y de vez en cuando, un Not-A-Number entraba debido a pequeños errores de redondeo y también lo solucionaba bien.

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

El código era bastante sólido, pero tenía hardware, y el hardware tiende a dar respuestas confusas a veces.

Fue diseñado para funcionar sin intervención humana durante meses. Funcionó extremadamente bien en nuestras pruebas.

Como parte del código de recuperación de error, podría recurrirse a reiniciar todo el edificio utilizando la capacidad del UPS para apagarse en N minutos y encenderse en M minutos.

A veces las fallas de hardware necesitan un ciclo de encendido :)

Si mal no recuerdo, el último recurso después de un ciclo de energía sin éxito fue enviar un correo electrónico a sus propietarios, diciendo "Intenté solucionarlo y no puedo, el problema está en el subsistema XYZ" e incluí un enlace para obtener un soporte llama de nuevo a nosotros

Lamentablemente, el proyecto se conservó antes de que pudiera ser consciente de sí mismo:)>


Personalmente, siempre me han dicho que quieres capturar todas las Excepciones de Runtime; sin embargo, también debe hacer algo acerca de 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.

Edición 1: Como dijo kdgregory, atrapar e ignorar son dos cosas diferentes, en general, las personas se oponen a lo último :-)


RuntimeException está destinado a ser utilizado para errores del programador. Como tal, nunca debería ser atrapado. Hay algunos casos donde debería ser:

  1. está llamando al código que proviene de un tercero en el que no tiene control sobre cuándo emiten 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, tendría que preguntar por qué está teniendo RuntimeExceptions en las pruebas; debería arreglarlas en lugar de solucionarlas.

Por lo tanto, debe garantizar que su código solo arroje RuntimeExceptions cuando desee 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.

Puedes ver esta discusión por otras razones que las personas dan ... Personalmente, no he encontrado una razón convincente en las respuestas.


Si es razonable esperar 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 . Por favor, lea estas Docs


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; Al igual que FileNotFoundException no es el programador el que coloca los archivos en la unidad del usuario si el programa realmente está tratando de leer el archivo 1.txt que se supone que está allí en f:/ de usuario con las instrucciones:

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

Si 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 falla con un 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.

Permítanme también explicar el segundo escenario con el cual el concepto de RuntimeException será claro. Considera seguir el código:

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

Esta es una codificación pobre que genera la 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.


RuntimeException cuando quieres 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.


RuntimeException por el mismo motivo por el que captas cualquier excepción: planeas hacer algo con él. 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.

Sin embargo, detectar e ignorar cualquier excepción es una práctica extremadamente mala.