El Método A llama a un Método B que a su vez llama al Método C.
No hay manejo de excepciones en MethodB o MethodC. Pero hay un manejo de excepciones en el Método A.
En MethodC ocurre una excepción.
Ahora, esa excepción está apareciendo en el Método A, que lo maneja adecuadamente.
¿Qué hay de malo en esto?
En mi opinión, en algún momento una persona que llama ejecutará MethodB o MethodC, y cuando se produzcan excepciones en esos métodos, lo que se obtendrá al manejar excepciones dentro de esos métodos, que esencialmente es solo un bloque try / catch / finally en lugar de simplemente dejarlo ellos burbujean hasta el llamado?
La declaración o consenso sobre el manejo de excepciones es arrojar cuando la ejecución no puede continuar debido a eso, una excepción. Lo entiendo. Pero, ¿por qué no atrapar la excepción más arriba en la cadena en lugar de tener bloques try / catch hasta el final?
Lo entiendo cuando necesitas liberar recursos. Esa es una cuestión completamente diferente.
fuente
try-catch
bloqueo en absoluto.Result<T>
tipo (un tipo que almacene un resultado de un cálculo o un error) y devolverlo de sus funciones de lanzamiento. Propagar un error en la pila implicaría leer cada valor de retorno, verificar si es un error y devolver un error si es así.Respuestas:
Como principio general, no capture excepciones a menos que sepa qué hacer con ellas. Si MethodC arroja una excepción, pero MethodB no tiene una forma útil de manejarla, entonces debería permitir que la excepción se propague hasta MethodA.
Las únicas razones por las que un método debe tener un mecanismo de captura y relanzamiento son:
De lo contrario, detectar excepciones en el nivel incorrecto tiende a generar un código que falla silenciosamente sin proporcionar comentarios útiles al código de llamada (y, en última instancia, al usuario del software). La alternativa de atrapar una excepción y luego volver a lanzarla inmediatamente no tiene sentido.
fuente
try ... finally ...
, entoncesLoadDataException
e incluya los detalles de la excepción original de acuerdo con las características de su idioma, de modo que los futuros encargados puedan ver la causa raíz sin tener que adjuntar un depurador y descubrir cómo reproducir el problema.Absolutamente nada.
"lo maneja adecuadamente" es la parte importante. Ese es el quid de la gestión de excepciones estructuradas.
Si su código puede hacer algo "útil" con una excepción, hágalo. Si no, entonces déjalo bien.
Eso es exactamente lo que deberías estar haciendo. Si está leyendo el código que tiene manejadores / lanzadores "completamente", entonces [probablemente] está leyendo un código bastante pobre.
Lamentablemente, algunos desarrolladores simplemente ven los bloques de captura como código de "placa de caldera" que arrojan (sin juego de palabras) a cada método que escriben, a menudo porque realmente no "obtienen" el manejo de excepciones y piensan que tienen que agregar algo que las excepciones no "escapan" y matan su programa.
Parte de la dificultad aquí es que, la mayoría de las veces, este problema ni siquiera se notará, porque las excepciones no se lanzan todo el tiempo, pero cuando lo hacen , el programa va a perder mucho tiempo y Esfuerzo gradualmente para eliminar la pila de llamadas para llegar a un lugar que realmente hace algo útil con la excepción.
fuente
catch
en el nivel más alto posible que registre el error y devuelva una respuesta de error. Nocatch
bloques esparcidos por todas partes. Si no tiene ganas de enumerar todas las posibles excepciones marcadas (en lenguajes como Java), simplemente envuélvalas enRuntimeException
lugar de iniciar sesión allí, intentar continuar y encontrarse con más errores o incluso vulnerabilidades.Debe marcar la diferencia entre las bibliotecas y las aplicaciones.
Las bibliotecas pueden lanzar excepciones no capturadas libremente
Cuando diseña una biblioteca, en algún momento debe pensar qué puede salir mal. Los parámetros pueden estar en el rango incorrecto o
null
, los recursos externos pueden no estar disponibles, etc.Su biblioteca con mayor frecuencia no tendrá una manera de tratarlos de manera sensata . La única solución sensata es lanzar una Excepción apropiada y dejar que el desarrollador de la Aplicación se encargue de ella.
Las aplicaciones siempre deberían, en algún momento, detectar excepciones
Cuando se detecta una excepción, me gusta clasificarlos como errores o errores fatales . Un error regular significa que una sola operación dentro de mi aplicación falló. Por ejemplo, un documento abierto no se pudo guardar porque el destino no se podía escribir. Lo único que debe hacer la aplicación es informar al usuario que la operación no se pudo completar con éxito, proporcionar información legible para el problema y luego dejar que el usuario decida qué hacer a continuación.
Un error fatal es un error del que la lógica principal de la aplicación no puede recuperarse. Por ejemplo, si el controlador del dispositivo gráfico se bloquea en un videojuego, no hay forma de que la aplicación informe "con gracia" al usuario. En este caso, se debe escribir un archivo de registro y, si es posible, se debe informar al usuario de una forma u otra.
Incluso en un caso tan grave, la Aplicación debe manejar esta Excepción de manera significativa. Esto puede incluir escribir un archivo de registro, enviar un informe de bloqueo, etc. No hay ninguna razón para que la aplicación no responda a la excepción de alguna manera.
fuente
HDDPluggedOutDuringWritingException
pueda resolver un problema y no sea fatal para la aplicación. El programa puede decidir qué hacer con eso.Lo que está mal con el patrón que describe es que el método A no tendrá forma de distinguir entre tres escenarios:
El Método B falló de manera anticipada.
El método C falló de una manera no prevista por el método B, pero mientras el método B realizaba una operación que podría abandonarse de manera segura.
El método C falló de una manera no prevista por el método B, pero mientras el método B realizaba una operación que colocaba las cosas en un estado incoherente que supuestamente sería temporal, que B no pudo limpiar debido a la falla de C.
La única forma en que el método A podrá distinguir esos escenarios será si la excepción lanzada desde B incluye información suficiente para ese propósito, o si el desbobinado de la pila para el método B hace que el objeto quede en un estado explícitamente invalidado . Desafortunadamente, la mayoría de los marcos de excepción hacen que ambos patrones sean incómodos, lo que obliga a los programadores a tomar decisiones de diseño de "menor maldad".
fuente