¿Debería la capa de servicio capturar todas las excepciones de dao y envolverlas como excepciones de servicio?

23

Tengo una aplicación web Spring de tres capas: dao, servicio y controladores. Un controlador nunca llama directamente al dao, lo hace a través de la capa de servicio. En este momento, la mayoría de las veces si hay una excepción de dao (tiempo de ejecución) que no se maneja, será detectada por un JSP que muestra un mensaje de error al usuario final. ¿Debería la capa de servicio capturar todas las excepciones de dao y envolverlas como excepciones de servicio?

try {
   daoInstance.someDaoMethod();
} catch(DataAccessException dae) {
   throw new ServiceException("message", dae);
}

Supongamos que ServiceException también es tiempo de ejecución y tampoco se maneja. ¿Hay alguna diferencia para lanzar la DataAccessException en lugar de la ServiceException? Solo pensé que la capa de presentación no debería saber acerca de la excepción de acceso a datos. Pero no veo el punto de atrapar excepciones irrecuperables solo para envolverlas.

Oscar
fuente

Respuestas:

18

Creo que un factor importante es quiénes son sus clientes de servicio.

Si su capa de servicio es solo un límite arquitectónico entre capas en su propio proyecto, y el cliente de servicio está dentro del mismo ámbito de confianza, entonces está bien relajar las cosas y dejar que las excepciones no verificadas broten a la capa de controlador o al cliente de servicio.

Sin embargo, para el código público; servicio que es consumido por un tercero o cliente, creo que es más limpio envolver cualquier excepción no verificada con una excepción orientada al servicio, principalmente por cuestiones de seguridad, en segundo lugar por acoplamiento flojo y abstracción limpia.

Una excepción de la capa de datos nunca debe llegar directamente a un usuario final de una aplicación web . Potencialmente contiene información interna sobre su esquema, sus consultas, información de número de línea, nombres de variables o funciones, etc. Las excepciones del usuario final se pueden desinfectar en una configuración segura.

Un cliente de servicio externo no está preocupado con los detalles de su implementación, y de todos modos no puede manejar excepciones no verificadas, ya que son errores o problemas ambientales. En aplicaciones seguras, los errores de la base de datos simplemente no son lo suficientemente seguros como para propagarse, OracleException - ORA-01234 - ...que podría ser la tercera tabla que se insertó. Se debe permitir que el cliente se ocupe de cualquier excepción comprobada / esperada que pueda manejar, y trate todo lo demás como un posible informe de error. Su contrato de servicio debe ser una abstracción atómica, consistente y transaccional. Si no puede hacer nada con respecto a la excepción, entonces lo único útil que queda es darle un informe de error. Ya tiene la capacidad de registrar la excepción, entonces, ¿por qué cargar a su usuario final con los detalles? Su aplicación puede monitorearse para que ya sepa sobre las excepciones no verificadas antes de que los usuarios las denuncien.

Nunca está bien comer excepciones, ni soy fanático de las excepciones marcadas, pero prefiero tener un plan que sea apropiado para la naturaleza del producto en general.

Codenheim
fuente
13

No, no debe incluir excepciones DAO en una aplicación web

Hay mucho ruido en el código para beneficio cero. Las excepciones DAO son excepciones no marcadas por una buena razón. El código de la aplicación no puede hacer nada útil para recuperarse de una excepción DAO. El verdadero problema está aquí:

... será capturado por un JSP que muestra un mensaje de error al usuario final.

Solucione este problema en un lugar en lugar de desarmar toda la base de código.

Usted controla cómo se muestra una excepción no detectada al usuario. Las excepciones no detectadas se deben a errores de la aplicación o una falla en el sistema subyacente. No hay ninguna razón para darle al usuario información sobre la razón por la cual su solicitud no pudo ser atendida. No hay nada que el usuario pueda hacer. Todo lo que debe hacer es publicar una página de error amigable.

NB: si te encuentras escribiendo un montón de código tedioso, por ejemplo, creando un montón de bloques de captura que simplemente se envuelven y vuelven a lanzar, casi siempre hay una mejor solución.

Kevin Cline
fuente
Gracias por tu respuesta. Y sí, el jsp muestra un mensaje personalizado: "Vaya, algo salió mal". No muestra ninguna información sobre la excepción
Oscar
7

La razón principal por la que se usaría el ajuste de excepción es para evitar que el código en la capa empresarial tenga que conocer cada posible excepción en el sistema . Existen dos motivos principales para esto:

  • Consistencia: las excepciones declaradas se agregan hacia la parte superior de la pila de llamadas. Si no ajusta las excepciones, sino que las pasa declarando sus métodos para lanzarlas, puede terminar con métodos de nivel superior que declaran muchas excepciones diferentes. Declarar que todas estas excepciones en cada método respaldan la pila de llamadas se vuelve tedioso.

  • Encapsulación: es posible que no desee que sus componentes de nivel superior sepan nada sobre los componentes de nivel inferior, ni las excepciones que arrojan. Por ejemplo, el propósito de las interfaces e implementaciones DAO es abstraer los detalles del acceso a los datos lejos del resto de la aplicación. Ahora, si sus métodos DAO arrojan SQLException, entonces el código que usa los DAO tendrá que atraparlos. ¿Qué sucede si cambia a una implementación que lee los datos de un servicio web en lugar de una base de datos? Entonces sus métodos DAO tendrán que lanzar tanto RemoteException como SQLException. Y, si tiene un DAO que lee datos de un archivo, también necesitará lanzar IOException. Esas son tres excepciones diferentes, cada una vinculada a su propia implementación DAO.

Entonces, en resumen, ¡la respuesta es sí!

fabienbk
fuente
3
Las implementaciones de JPA (por ejemplo, Hibernate) arrojan excepciones no verificadas. No tienen que ser declarados o atrapados.
Kevin Cline