Arquitectura multicapa: ¿dónde debería implementar el manejo de errores?

13

Actualmente estoy refactorizando un gran subsistema con una arquitectura de múltiples capas, y estoy luchando para diseñar una estrategia efectiva de manejo y registro de errores.

Digamos que mi arquitectura consta de las siguientes tres capas:

  • Interfaz pública (I.E un controlador MVC)
  • capa de dominio
  • Capa de acceso a datos

Mi fuente de confusión es donde debo implementar el manejo de errores \ manejo:

  1. La solución más sencilla sería implementar el registro en el nivel superior (I.E la Interfaz Pública \ Controlador MVC). Sin embargo, esto se siente mal porque significa burbujear la excepción a través de las diferentes capas y luego registrarla; en lugar de registrar la excepción en su fuente.

  2. El registro de la excepción en su origen es, obviamente, la mejor solución porque tengo más información. Mi problema con esto es que no puedo capturar todas las excepciones en el origen sin capturar TODAS las excepciones, y en la capa de interfaz de dominio / público, esto llevará a la captura de excepciones que ya han sido detectadas, registradas y relanzadas por la siguiente capa .

  3. Otra estrategia posible es una combinación de # 1 y # 2; por lo que detecto excepciones específicas en la capa en la que es más probable que se lancen (I.E Captura, registro y relanzamiento de SqlExceptions en la capa de acceso a datos) y luego registre cualquier otra excepción no detectada en el nivel superior. Sin embargo, esto también requeriría que detectara y volviera a registrar todas las excepciones en el nivel superior, porque no puedo distinguir entre los errores que ya se registraron o se manejaron en comparación con los que no.

Ahora, obviamente, este es un problema en la mayoría de las aplicaciones de software, por lo que debe haber una solución estándar para este problema que haga que las excepciones se detecten en la fuente y se registren una vez; Sin embargo, no puedo ver cómo hacerlo yo mismo.

Tenga en cuenta que el título de esta pregunta es muy similar a ' Excepciones de registro en una aplicación de varios niveles " ', sin embargo, las respuestas en esa publicación carecen de detalles y no son suficientes para responder a mi pregunta.

    
pregunta KidCode 22.10.2017 - 22:19

2 respuestas

13

A tus preguntas:

  

La solución más sencilla sería implementar el registro en la parte superior   nivel

Tener la burbuja de excepción hasta el nivel superior es un enfoque absolutamente correcto y plausible. Ninguno de los métodos de capa superior intenta continuar algún proceso después de la falla, que generalmente no tiene éxito. Y una excepción bien equipada contiene toda la información necesaria para el registro. Y no hacer nada con las excepciones lo ayuda a mantener su código limpio y enfocado en la tarea principal en lugar de las fallas.

  

El registro de la excepción en su fuente es obviamente la mejor solución   Porque tengo la mayor información.

Eso es la mitad correcta. Sí, la información más útil está disponible allí. Pero recomendaría poner todo esto en el objeto de excepción (si no está ya allí) en lugar de registrarlo inmediatamente. Si inicia sesión en un nivel bajo, aún debe lanzar una excepción para informar a las personas que llaman que no completó su trabajo. Esto termina en varios registros del mismo evento.

Excepciones

Mi directriz principal es detectar y registrar excepciones solo en el nivel superior. Y todas las capas a continuación deben asegurarse de que toda la información de fallas necesaria se transporte hasta el nivel superior. Dentro de una aplicación de proceso único, p. Ej. en Java, esto significa principalmente no intentar / capturar o iniciar sesión en absoluto fuera del nivel superior.

A veces, desea que se incluya información de contexto en el registro de excepciones que no esté disponible en la excepción original, por ejemplo. la declaración SQL y los parámetros que se ejecutaron cuando se lanzó la excepción. Luego, puede capturar la excepción original y volver a lanzar una nueva, que contiene la original más el contexto.

Por supuesto, la vida real a veces interfiere:

  • En Java, a veces tienes que atrapar una excepción y envolverla en un tipo de excepción diferente solo para obedecer algunas firmas de métodos fijos. Pero si vuelves a lanzar una excepción, asegúrate de que la relanzada contenga toda la información necesaria para el registro posterior.

  • Si está cruzando un borde entre procesos, a menudo técnicamente no puede transferir el objeto de excepción completo, incluido el seguimiento de la pila. Y, por supuesto, la conexión podría perderse. Así que aquí hay un punto en el que un servicio debe registrar excepciones y luego hacer todo lo posible para transmitir la mayor cantidad posible de información de fallas a través de la línea a su cliente. El servicio debe asegurarse de que el cliente reciba un aviso de falla, ya sea recibiendo una respuesta de falla o ejecutando un tiempo de espera en caso de una conexión rota. Por lo general, esto provocará que se registre el mismo error dos veces, una vez dentro del servicio (con más detalles) y una vez en el nivel superior del cliente.

Registro

Estoy agregando algunas oraciones sobre el registro en general, no solo el registro de excepciones.

Además de las situaciones excepcionales, desea que las actividades importantes de su aplicación se registren también en el registro. Por lo tanto, utilice un marco de registro.

Tenga cuidado con los niveles de registro (leer los registros en los que la información de depuración y los errores graves no se marcan de forma diferente es un dolor). Los niveles de registro típicos son:

  • ERROR: Algunas funciones fallaron de forma irrecuperable. Eso no significa necesariamente que todo el programa se bloqueó, pero no se pudo completar alguna tarea. Normalmente, tiene un objeto de excepción que describe el error.
  • ADVERTENCIA: Ocurrió algo extraño, pero no causó errores en ninguna tarea (se detectó una configuración extraña, el fallo temporal de la conexión causó algunos reintentos, etc.)
  • INFO: desea comunicar alguna acción importante del programa al administrador del sistema local (iniciando algún servicio con su configuración y versión de software, importando archivos de datos a la base de datos, usuarios que inician sesión en el sistema, se le ocurre la idea ...) .
  • DEBUG: las cosas que usted, como desarrollador, desea ver cuando está depurando algún problema (pero nunca sabrá de antemano lo que realmente necesita en caso de este o ese error específico; si puede preverlo, arreglar el error). Una cosa que siempre es útil es registrar actividades en interfaces externas.

En producción, establezca el nivel de registro en INFO. Los resultados deben ser útiles para un administrador del sistema para que sepa lo que está pasando. Espere que lo llame para solicitar asistencia o solución de errores para cada ERROR en el registro y la mitad de las ADVERTENCIAS.

Habilite el nivel DEBUG solo durante las sesiones de depuración reales.

Agrupe las entradas del registro en categorías apropiadas (por ejemplo, por el nombre de clase completamente calificado del código que genera la entrada), lo que le permite activar los registros de depuración para partes específicas de su programa.

    
respondido por el Ralf Kleberhoff 23.10.2017 - 15:34
-1

Me estoy preparando para los votos negativos, pero voy a arriesgarme y decir que no estoy seguro de que pueda estar de acuerdo con esto.

Al aumentar las excepciones, mucho menos volver a registrarlas, es un esfuerzo extra con poco beneficio. Capture la excepción en la fuente (sí, la más fácil), inicie sesión, pero luego no vuelva a lanzar la excepción, simplemente informe "error" a la persona que llama. "-1", nulo, cadena vacía, alguna enumeración, lo que sea. La persona que llama solo necesita saber que la llamada falló, casi nunca los detalles horripilantes. Y esos estarán en tu registro, ¿verdad? En el caso poco frecuente de que la persona que llama necesite los detalles, siga adelante y haga una burbuja, pero no como un valor predeterminado automático e irreflexivo.

    
respondido por el mickeyf 26.04.2018 - 23:48

Lea otras preguntas en las etiquetas