¿Es una buena práctica atrapar una excepción marcada y lanzar una RuntimeException?

70

Leí un código de un colega y descubrí que a menudo atrapa varias excepciones y siempre lanza una 'RuntimeException' en su lugar. Siempre pensé que esta es una muy mala práctica. ¿Me equivoco?

RoflcoptrException
fuente
17
"El precio de las excepciones marcadas es una violación del Principio Abierto / Cerrado. Si arroja una excepción marcada de un método en su código y la captura está tres niveles arriba, debe declarar esa excepción en la firma de cada método entre usted y la captura "Esto significa que un cambio en un nivel bajo del software puede forzar cambios en la firma en muchos niveles superiores". —Robert C. Martin, «Código limpio», página 107
Songo
66
Es interesante notar que Jim Waldo despotrica contra las excepciones no verificadas en "Java: The Good Parts" shop.oreilly.com/product/9780596803742.do diciendo que los programadores adultos solo deberían lanzar excepciones marcadas. ¡Lo leímos en nuestro JUG hace solo 6 años cuando salió y parecía un buen consejo! Ahora, con la programación funcional, las excepciones comprobadas son completamente difíciles de manejar. Idiomas como Scala y Kotlin ni siquiera los tienen. También comencé a ajustar las excepciones sin marcar.
GlenPeterson
@GlenPeterson también tiene el consejo en FP para evitar exenciones por completo y usar tipos de suma en su lugar
jk.
También está el caso evidente de interfaces funcionales: las interfaces funcionales incorporados (es decir Function, Predicate, etc.) no han parametrizados lanza cláusulas. Esto significa que necesita atrapar, ajustar y volver a lanzar cualquier excepción marcada en el bucle interno de cualquier método stream (). Eso en sí mismo me ayuda a determinar si las excepciones marcadas son una mala idea.
Joel Cornett
No hay nada de malo en crear subclases personalizadas de RuntimeException para comunicar el significado a través de su excepción.
Joel Cornett

Respuestas:

55

No conozco suficiente contexto para saber si su colega está haciendo algo incorrectamente o no, así que voy a discutir sobre esto en un sentido general.

No creo que siempre sea una práctica incorrecta convertir las excepciones verificadas en una especie de excepción de tiempo de ejecución . Las excepciones marcadas a menudo son mal utilizadas y abusadas por los desarrolladores.

Es muy fácil usar excepciones comprobadas cuando no están destinadas a ser utilizadas (condiciones irrecuperables, o incluso controlar el flujo). Especialmente si se usa una excepción marcada para condiciones de las cuales la persona que llama no puede recuperarse, creo que está justificado convertir esa excepción en una excepción de tiempo de ejecución con un mensaje / estado útil. Desafortunadamente, en muchos casos, cuando uno se enfrenta a una condición irrecuperable, tiende a tener un bloque de captura vacío, que es una de las peores cosas que puede hacer. La depuración de este problema es uno de los mayores problemas que puede encontrar un desarrollador.

Entonces, si cree que está lidiando con una condición recuperable, debe manejarse en consecuencia y la excepción no debe convertirse en una excepción de tiempo de ejecución. Si se usa una excepción marcada para condiciones irrecuperables, se justifica convertirla en una excepción de tiempo de ejecución .

c_maker
fuente
17
En la mayoría de las aplicaciones de la vida real, hay muy pocas condiciones irrecuperables. Casi siempre hubo algún nivel en el que puede y debe decir "OK, esta acción falló, por lo que mostramos / registramos un buen mensaje de error y continuamos / esperamos el próximo".
Michael Borgwardt
66
Eso es cierto, @MichaelBorgwardt, pero el lugar para ese tipo de manejo a menudo está en el nivel más alto de la aplicación, por lo que cada vez que veo que los desarrolladores "manejan" excepciones en niveles inferiores, generalmente es fácil eliminar su manejo y simplemente filtrar la excepción hacia arriba. Por ejemplo, un marco web como JSF detecta excepciones al más alto nivel, imprime mensajes de registro y continúa procesando otras solicitudes (sin decir que el manejo predeterminado es adecuado, solo un ejemplo).
DavidS
40

Se puede ser bueno . Por favor lee:

http://onjava.com/pub/a/onjava/2003/11/19/exceptions.html

La mayoría de las veces, el código del cliente no puede hacer nada sobre las excepciones SQLE. No dude en convertirlos en excepciones no verificadas. Considere la siguiente pieza de código:

public void dataAccessCode(){
  try{
      ..some code that throws SQLException
  }catch(SQLException ex){
      ex.printStacktrace();
  }
} 

Este bloque de captura simplemente suprime la excepción y no hace nada. La justificación es que no hay nada que mi cliente pueda hacer sobre una excepción SQLException. ¿Qué tal lidiar con esto de la siguiente manera?

public void dataAccessCode(){
   try{
       ..some code that throws SQLException
   }catch(SQLException ex){
       throw new RuntimeException(ex);
   }
} 

Esto convierte SQLException en RuntimeException. Si se produce SQLException, la cláusula catch produce una nueva RuntimeException. El hilo de ejecución se suspende y se informa la excepción. Sin embargo, no estoy corrompiendo mi capa de objeto comercial con un manejo de excepciones innecesario, especialmente porque no puede hacer nada con respecto a una excepción SQLException. Si mi captura necesita la causa de la excepción raíz, puedo usar el método getCause () disponible en todas las clases de excepción a partir de JDK1.4.

Lanzar excepciones comprobadas y no poder recuperarse de eso no ayuda.

Algunas personas incluso piensan que las excepciones marcadas no deberían usarse en absoluto. Ver http://www.ibm.com/developerworks/java/library/j-jtp05254/index.html

Recientemente, varios expertos bien considerados, incluidos Bruce Eckel y Rod Johnson, han declarado públicamente que, si bien inicialmente estuvieron completamente de acuerdo con la posición ortodoxa sobre las excepciones verificadas, han concluido que el uso exclusivo de las excepciones marcadas no es una idea tan buena como esta. apareció al principio, y las excepciones comprobadas se han convertido en una fuente importante de problemas para muchos proyectos grandes. Eckel tiene una visión más extrema, sugiriendo que todas las excepciones deben ser desmarcadas; El punto de vista de Johnson es más conservador, pero aún sugiere que la preferencia ortodoxa por las excepciones controladas es excesiva. (Vale la pena señalar que los arquitectos de C #, que casi con certeza tenían mucha experiencia en el uso de la tecnología Java, optaron por omitir las excepciones marcadas del diseño del lenguaje, haciendo que todas las excepciones no estén marcadas.

También desde el mismo enlace:

La decisión de usar excepciones no verificadas es complicada, y está claro que no hay una respuesta obvia. El consejo de Sun es usarlos para nada, el enfoque de C # (con el que Eckel y otros están de acuerdo) es usarlos para todo. Otros dicen, "hay un término medio".

mrmuggles
fuente
13

No, no estas mal. Su práctica es extremadamente equivocada. Debe lanzar una excepción que capture el problema que lo causó. RunTimeException es amplio y exagerado. Debe ser una excepción NullPointerException, ArgumentException, etc. Lo que describa con precisión lo que salió mal. Esto proporciona la capacidad de diferenciar los problemas que debe manejar y dejar que el programa sobreviva frente a los errores que deberían ser un escenario de "No pasar". Lo que está haciendo es solo un poco mejor que "Al reiniciar error después", a menos que falte algo en la información proporcionada en la pregunta.

Aparejo
fuente
1
Gracias por la pista. ¿Y qué pasa si lanza una excepción personalizada que ha implementado que hereda directamente de RuntimeException?
RoflcoptrException
27
@Gary Buyn: Mucha gente piensa que excepción comprobada son un experimento de diseño del lenguaje fallado y que son los que deben utilizarse con moderación, no como una cuestión de hábito.
Michael Borgwardt
77
@Gary Buyn: Aquí hay un artículo que describe el debate bastante bien: ibm.com/developerworks/java/library/j-jtp05254/index.html Tenga en cuenta también que más de 15 años después de que Java introdujo esta característica, ningún otro lenguaje la ha adoptado, y C ++ ha desaprobado una característica similar.
Michael Borgwardt
77
@c_maker: En realidad, Bloch promueve principalmente la visión ortodoxa, y su comentario parece ser principalmente sobre el uso de más excepciones, punto. Mi opinión es que la única razón válida para usar una excepción marcada es una condición que usted espera que todas las personas que llaman manejen de inmediato.
Michael Borgwardt
14
Lanzar innecesariamente las excepciones marcadas viola la encapsulación. ¿Qué haces si un método simple como 'getAccounts ()' te arroja una 'SQLException', 'NullPointerException' o 'FileNotFoundException'? ¿Puedes controlarlo? Probablemente solo lo 'atrape (Excepción e) {}'. Además, esas excepciones: ¡su implementación específica! ¡No debería ser parte del contrato! Todo lo que necesita saber es que hubo un error . ¿Y qué pasa si la implementación cambia? De repente, todo tiene que cambiar, porque el método ya no arroja 'SQLException', sino una 'ParseXMLException'.
KL
8

Depende.

Esta práctica puede ser incluso sabia . Hay muchas situaciones (por ejemplo, en el desarrollo web), en las que si ocurre alguna excepción, no puede hacer nada (porque no puede, por ejemplo, reparar la DB inconsistente de su código :-), solo el desarrollador puede hacerlo). En estas situaciones, es aconsejable envolver la excepción lanzada en una excepción de tiempo de ejecución y volver a lanzarla. De lo que puede capturar todas estas excepciones en alguna capa de manejo de excepciones, registre el error y muestre al usuario algún buen código de error localizado + mensaje.

Por otro lado , si la excepción no es tiempo de ejecución (está marcada), el desarrollador de la API indica que esta excepción se puede resolver y debe repararse. Si es posible, definitivamente deberías hacerlo.

La otra solución podría ser volver a lanzar esta excepción marcada en la capa de llamada, pero si no pudo resolverla, donde ocurrió la excepción, es probable que tampoco pueda resolverla aquí ...

malejpavouk
fuente
Espera que el desarrollador de la API supiera lo que estaba haciendo y utilizara bien las excepciones comprobadas. Comencé a ver API que favorecen lanzar excepciones de tiempo de ejecución y al mismo tiempo documentarlo para que el cliente tenga la opción de atraparlo si lo desea.
c_maker
Un método que arroja una excepción generalmente no puede saber si una persona que llama podría recuperarse de él. Por otro lado, sugeriría que un método solo debe permitir que una excepción marcada lanzada por un método interno escape si sabe por qué el método interno arrojó la excepción, y la razón es consistente con la API del método externo. Si un método interno arroja una excepción marcada inesperadamente, dejarla aparecer como una excepción marcada puede dejar a la persona que llama mal informada sobre lo que sucedió.
supercat
2
Gracias por mencionar el exception handling layer- por ejemplo, en una aplicación web, un filtro.
Jake Toronto
5

Me gustaría recibir comentarios sobre esto, pero creo que hay momentos en que esto no es necesariamente una mala práctica. (O terriblemente mal). Pero tal vez estoy equivocado.

Muchas veces, una API que está utilizando arrojará una excepción que no puede imaginar que realmente se arroje en su caso de uso específico. En este caso, parece perfectamente correcto lanzar una RuntimeException con la excepción capturada como la causa. Si se lanza esta excepción, es probable que sea la causa del error de programación y no esté dentro de los límites para la especificación correcta.

Suponiendo que RuntimeException no se detecta e ignora más tarde, no está cerca de un OnErrorResumeNext.

OnErrorResumeNext ocurriría cuando alguien detecta una excepción y simplemente la ignora o simplemente la imprime. Esta es una práctica terriblemente mala en casi todos los casos.

usuario606723
fuente
Este podría ser el caso cerca de la parte superior del árbol de llamadas, donde lo único que puede hacer es intentar recuperarse con gracia y saber que el error específico realmente no ayudará. En ese caso, es posible que deba registrar el error y seguir adelante (procesar el siguiente registro, informar al usuario de que se produjo un error, etc.). De otra manera no. Siempre debe manejar las excepciones tan cerca del error como sea práctico, no envolverlas como un elefante blanco para el próximo controlador.
Michael K
@MichaelK El problema es "tan cerca del error como sea práctico" en la práctica a menudo significa "a través de varias capas intermedias que están fuera de su control directo". Por ejemplo, si mi clase tiene que implementar una determinada interfaz, mis manos están atadas. Eso puede suceder arbitrariamente en lo profundo del árbol de llamadas. Incluso cuando las interfaces están bajo mi control, agregar declaraciones de lanzamiento puede hacer que la abstracción se filtre si solo hay un conjunto limitado de implementaciones concretas que posiblemente puedan lanzar. Hacer que cada cliente pague el costo de los detalles de implementación de unos pocos no es una gran compensación para el diseño de la OMI.
Tim Seguine
4

TL; DR

Premisa

  • Se deben generar excepciones de tiempo de ejecución cuando el error es irrecuperable: cuando el error está en el código y no depende del estado externo (por lo tanto, la recuperación estaría corrigiendo el código).
  • Se deben generar excepciones marcadas cuando el código es correcto, pero el estado externo no es el esperado: no hay conectividad de red, no se encuentra el archivo o está dañado, etc.

Conclusión

Podemos volver a lanzar una excepción marcada como una excepción de tiempo de ejecución si el código de propagación o interfaz supone que la implementación subyacente depende del estado externo, cuando claramente no lo hace.


Esta sección discute el tema de cuándo se debe lanzar cualquiera de las excepciones. Puede pasar a la siguiente barra horizontal si solo desea leer una explicación más detallada de la conclusión.

¿Cuándo es apropiado lanzar una excepción de tiempo de ejecución? Lanza una excepción de tiempo de ejecución cuando está claro que el código es incorrecto y que la recuperación es apropiada modificando el código.

Por ejemplo, es apropiado lanzar una excepción de tiempo de ejecución para lo siguiente:

float nan = 1/0;

Esto arrojará una división por cero excepción de tiempo de ejecución. Esto es apropiado porque el código es defectuoso.

O, por ejemplo, aquí hay una parte del HashMapconstructor de:

public HashMap(int initialCapacity, float loadFactor) {
    if (initialCapacity < 0)
        throw new IllegalArgumentException("Illegal initial capacity: " + initialCapacity);
    if (initialCapacity > MAXIMUM_CAPACITY)
        initialCapacity = MAXIMUM_CAPACITY;
    if (loadFactor <= 0 || Float.isNaN(loadFactor))
        throw new IllegalArgumentException("Illegal load factor: " +
                loadFactor);
    // more irrelevant code...
}

Para corregir la capacidad inicial o el factor de carga, es apropiado que edite el código para asegurarse de que se pasan los valores correctos. No depende de que algún servidor lejano esté activo, del estado actual del disco, un archivo u otro programa. Ese constructor que se llama con argumentos no válidos depende de la exactitud del código de llamada, ya sea un cálculo incorrecto que condujo a los parámetros no válidos o al flujo inapropiado que omitió un error.

¿Cuándo es apropiado lanzar una excepción marcada? Lanza una excepción marcada cuando el problema es recuperable sin cambiar el código. O para decirlo en términos diferentes, arroja una excepción marcada cuando el error está relacionado con el estado mientras el código es correcto.

Ahora la palabra "recuperar" puede ser difícil aquí. Podría significar que encuentra otra forma de lograr el objetivo: por ejemplo, si el servidor no responde, debe probar el siguiente servidor. Si ese tipo de recuperación es posible para su caso, entonces eso es genial, pero eso no es lo único que significa la recuperación: la recuperación podría simplemente mostrar un diálogo de error al usuario que explica lo que sucedió, o si esa es una aplicación de servidor, entonces podría ser enviando un correo electrónico al administrador, o incluso simplemente registrando el error de manera adecuada y concisa.

Tomemos el ejemplo que se mencionó en la respuesta de mrmuggles:

public void dataAccessCode(){
   try{
       ..some code that throws SQLException
   }catch(SQLException ex){
       throw new RuntimeException(ex);
   }
}

Esta no es la forma correcta de manejar la excepción marcada. La mera incapacidad para manejar la excepción en el alcance de este método no significa que la aplicación deba bloquearse. En cambio, es apropiado propagarlo a un alcance superior de esta manera:

public Data dataAccessCode() throws SQLException {
    // some code that communicates with the database
}

Lo que permite la posibilidad de recuperación por parte de la persona que llama:

public void loadDataAndShowUi() {
    try {
        Data data = dataAccessCode();
        showUiForData(data);
    } catch(SQLException e) {
        // Recover by showing an error alert dialog
        showCantLoadDataErrorDialog();
    }
}

Las excepciones marcadas son una herramienta de análisis estático, dejan en claro para un programador lo que podría salir mal en una determinada llamada sin requerirles que aprendan la implementación o pasen por un proceso de prueba y error. Esto facilita asegurar que no se ignorará ninguna parte del flujo de error. Volver a lanzar una excepción marcada como una excepción de tiempo de ejecución funciona en contra de esta función de análisis estático que ahorra trabajo.

También vale la pena mencionar que la capa de llamada tiene un mejor contexto del esquema más amplio de las cosas como se ha demostrado anteriormente. Podría haber muchas causas para que dataAccessCodese llamara, la razón específica de la llamada solo es visible para la persona que llama, por lo que puede tomar una mejor decisión en la recuperación correcta en caso de falla.

Ahora que tenemos esta distinción clara, podemos proceder a deducir cuándo está bien volver a lanzar una excepción marcada como una excepción de tiempo de ejecución.


Dado lo anterior, ¿cuándo es apropiado volver a lanzar una excepción marcada como RuntimeException? Cuando el código que está utilizando asume dependencia del estado externo, pero puede afirmar claramente que no depende del estado externo.

Considera lo siguiente:

StringReader sr = new StringReader("{\"test\":\"test\"}");
try {
    doesSomethingWithReader(sr); // calls #read, so propagates IOException
} catch (IOException e) {
    throw new IllegalStateException(e);
}

En este ejemplo, el código se propaga IOExceptionporque la API de Readerestá diseñada para acceder al estado externo, sin embargo, sabemos que la StringReaderimplementación no accede al estado externo. En este ámbito, donde ciertamente podemos afirmar que las partes involucradas en la llamada no acceden a E / S ni a ningún otro estado externo, podemos volver a lanzar la excepción de manera segura como una excepción de tiempo de ejecución sin sorprender a los colegas que desconocen nuestra implementación (y posiblemente asumiendo que el código de acceso IO arrojará un IOException).


La razón para mantener estrictamente marcadas las excepciones dependientes del estado externo es que no son deterministas (a diferencia de las excepciones dependientes de la lógica, que previsiblemente se reproducirán cada vez para una versión del código). Por ejemplo, si intenta dividir por 0, siempre producirá una excepción. Si no divide entre 0, nunca producirá una excepción, y no tiene que manejar ese caso de excepción, porque nunca sucederá. Sin embargo, en el caso de acceder a un archivo, tener éxito una vez no significa que tendrá éxito la próxima vez: el usuario podría haber cambiado los permisos, otro proceso podría haberlo eliminado o modificado. Entonces, siempre tiene que manejar ese caso excepcional, o es probable que tenga un error.

Ben Barkay
fuente
2

Para aplicaciones independientes. Cuando sepa que su aplicación no puede manejar la excepción que podría, en lugar de lanzar la RuntimeException marcada, lanzar Error, dejar que la aplicación se bloquee, esperar informes de errores y corregir su aplicación. (Vea la respuesta de mrmuggles para una discusión más profunda de los pros y los contras de verificado versus no verificado).

Kasper van den Berg
fuente
2

Esta es una práctica común en muchos marcos. Por ejemplo, Hibernatehace exactamente esto. La idea es que las API no deben ser intrusivas para el lado del cliente y Exceptionson intrusivas ya que debe escribir explícitamente el código para manejarlas en el lugar donde llama a la API. Pero ese lugar podría no ser el lugar correcto para manejar la excepción en primer lugar.
En realidad, para ser honesto, este es un tema "candente" y muchas disputas, por lo que no voy a tomar partido, pero diré que lo que hace / propone su amigo no es inusual o poco común.

usuario10326
fuente
1

Toda la "excepción marcada" es una mala idea.

La programación estructurada solo permite que la información pase entre funciones (o, en lenguaje Java, métodos) cuando están "cerca". Más precisamente, la información solo puede moverse a través de las funciones de dos maneras:

  1. De una persona que llama a una persona que llama, pasando por un argumento de paso

  2. De un llamado a su llamador, como valores de retorno.

Esto es algo fundamentalmente bueno. Esto es lo que le permite razonar sobre su código localmente: si necesita comprender o modificar una parte de su programa, solo necesita mirar esa parte y otras "cercanas".

Sin embargo, en algunas circunstancias, es necesario enviar información a una función "distante", sin que nadie en el medio "sepa". Esto es precisamente cuando hay que usar excepciones. Una excepción es un mensaje secreto enviado desde un generador (cualquier parte de su código puede contener una throwdeclaración) a un controlador (cualquier parte de su código puede contener un catchbloque que sea compatible con la excepción que era thrown).

Las excepciones marcadas destruyen el secreto del mecanismo y, con él, la razón misma de su existencia. Si una función puede permitirse que la persona que llama "conozca" una información, simplemente envíe esa información directamente como parte del valor de retorno.

pyon
fuente
Puede ser bueno mencionar que este tipo de problema realmente puede causar estragos en los casos en que un método ejecuta una función que es suministrada por su llamador. El autor del método que recibe la función en muchos casos no tendrá razón para saber ni preocuparse por lo que la persona que llama espera que haga, ni qué excepciones podría estar esperando. Si el código que recibe el método no espera que arroje una excepción verificada, es posible que el método que se suministra tenga que envolver cualquier excepción verificada que arrojaría excepciones no verificadas que su proveedor podría atrapar.
supercat
0

Esto podría depender de cada caso. En ciertos escenarios, es aconsejable hacer lo que su amigo está haciendo, por ejemplo, cuando está exponiendo una API para algunos clientes y desea que el cliente sea menos consciente de los detalles de implementación, donde sabe que ciertas excepciones de implementación pueden ser específicas para detalles de implementación y no expuestos al cliente.

Al mantener las excepciones marcadas fuera del camino, puede exponer las API que permitirían al cliente escribir un código más limpio, ya que el propio cliente podría estar validando previamente las condiciones excepcionales.

Por ejemplo, Integer.parseInt (String) toma una cadena y devuelve el número entero equivalente de ella y lanza NumberFormatException en caso de que la cadena no sea numérica. Ahora imagine que un envío de formulario con un campo agese convierte a través de este método, pero el cliente ya habría asegurado la validación por su parte, por lo que no tiene sentido forzar la verificación de excepción.

usuario94369
fuente
0

Realmente hay un par de preguntas aquí

  1. ¿Debería transformar las excepciones marcadas en no marcadas?

La regla general es que se deben verificar las excepciones que se espera que la persona que llama atrape y se recupere. Otras excepciones (aquellas en las que el único resultado razonable es abortar toda la operación o cuando las considere lo suficientemente improbables como para que no valga la pena preocuparse por manejarlas específicamente).

A veces, su juicio sobre si una excepción merece captura y recuperación es diferente de la de la API con la que está trabajando. A veces el contexto importa, una excepción que vale la pena manejar en una situación puede no valer la pena en otra. A veces su mano es forzada por las interfaces existentes. Entonces, sí, hay razones legítimas para convertir una excepción marcada en una excepción no verificada (o en un tipo diferente de excepción marcada)

  1. Si va a convertir una excepción no verificada en una excepción marcada, ¿cómo debe hacerlo?

En primer lugar y lo más importante, asegúrese de utilizar el recurso de encadenamiento de excepciones. De esa forma, la información de la excepción original no se pierde y puede usarse para la depuración.

En segundo lugar, debe decidir qué tipo de excepción utilizar. El uso de una excepción de tiempo de ejecución simple hace que sea más difícil para la persona que llama determinar qué salió mal, pero si la persona que llama está tratando de determinar qué salió mal, eso puede ser una indicación de que no debería haber cambiado la excepción para que no esté marcada.

Peter Green
fuente
0

En una pregunta booleana, es difícil responder de manera diferente después de dos respuestas controvertidas, pero me gustaría darle una perspectiva que, incluso mencionada en pocos lugares, no estaba lo suficientemente estresada por la importancia que tiene.

Con los años descubrí que siempre alguien está confundido acerca de un problema trivial, carece de la comprensión de algunos de los fundamentos.

Capas. Una aplicación de software (al menos se supone que es) un montón de capas una encima de otra. Una expectativa importante para una buena estratificación es que las capas inferiores brindan funcionalidad para componentes potencialmente múltiples de la capa superior.

Digamos que su aplicación tiene las siguientes capas de abajo hacia arriba NET, TCP, HTTP, REST, DATA MODEL, BUSINESS.

Si su capa de negocios desea ejecutar una llamada de descanso ... espere un segundo. ¿Por qué dije eso? ¿Por qué no dije solicitud HTTP o transacción TCP o envié paquetes de red? Porque esos son irrelevantes para mi capa empresarial. No voy a manejarlos, no voy a mirar los detalles de ellos. Estoy perfectamente bien si están profundamente en las excepciones que obtengo como causa y no quiero saber si existen.

Lo que es más, es malo si conozco los detalles, porque si mañana quisiera cambiar los protocolos de transporte subrayados que tratan los detalles que son específicos del protocolo TCP significa que mi abstracción REST no hizo un buen trabajo para abstraerse de La implementación específica.

Al realizar una transición de una capa a otra, es importante volver a visitar todos los aspectos y el sentido que tendrá para la abstracción que proporciona la capa actual. Puede ser reemplazar la excepción con otra, puede combinar varias excepciones. También podría hacer la transición de marcado a no marcado o viceversa.

Por supuesto, los lugares reales que mencionó tienen sentido es una historia diferente, pero en general, sí, podría ser algo bueno.

gsf
fuente
-2

En mi opinión,

En el nivel de marco, deberíamos capturar excepciones de tiempo de ejecución para reducir más bloque de try catch al invocador en el mismo lugar.

En el nivel de aplicación, raramente capturamos excepciones de tiempo de ejecución y creo que esta práctica fue mala.

Mark xie
fuente
1
¿Y qué harás con esas excepciones a nivel de marco?
Matthieu
Si hay una capa de interfaz de usuario en el marco que puede manejar las excepciones, entonces la interfaz de usuario presentaría un mensaje de error de algún tipo de que algo salió mal. En el caso de una aplicación de JavaScript de una página, la aplicación podría presentar un mensaje de error. Por supuesto, la capa de interfaz de usuario debe manejar el error solo si una capa más profunda realmente no puede recuperarse del error.
Jake Toronto