18

Desde que Microsoft presentó los bloques de aplicaciones, me he topado con gente que usa el Exception Handling Application Block. Recientemente, he tenido una mirada más cercana y resumiría la funcionalidad básica de la siguiente manera (omita el siguiente bloque si ya sabe lo que hace):Bloque de manejo de excepciones de Microsoft: ¿no es un ejemplo perfecto para la sobreingeniería?

El bloque de aplicación de manejo de excepciones tiene como objetivo centralizar y hacer completamente configurable con los archivos de configuración de la siguiente key exception handling tasks:

  • registro una excepción
  • Sustitución de una excepción
  • Envolviendo una excepción
  • Propa gating una excepción
  • etc.

La biblioteca hace que al tener que modificar sus bloques intento de captura de la siguiente manera:

try 
{ 
    // Run code. 
} 
catch(DataAccessException ex) 
{ 
    bool rethrow = ExceptionPolicy.HandleException(ex, "Data Access Policy"); 
    if (rethrow) 
    { 
     throw; 
    } 
} 

Sobre la base de lo que se especifica en el app.config para el nombre de la directiva (see here for docs), o bien HandleException ...

  • lanzar una nueva excepción (reemplazar la excepción original)
  • envuelve la excepción original en una nueva y tira que
  • traga la excepción (es decir no hacer nada)
  • tienen que volver a lanzar la excepción original

Además también se puede configurar para hacer más cosas de antemano (por ejemplo, registrar la excepción).

Ahora aquí está mi problema: completamente no veo cómo puede ser beneficioso hacer que sea configurable si una excepción se reemplaza, envuelve, se traga o se vuelve a tirar. En mi experiencia, esta decisión debe tomarse en el momento de escribir el código porque, por lo general, tendrá que cambiar el código circundante o de llamada cuando cambie el comportamiento de manejo de excepciones.

Por ejemplo, es probable que su código comience a comportarse incorrectamente cuando se reconfigura de modo que una excepción particular lanzada en un punto particular se trague en vez de volver a lanzar (puede haber código después del bloque catch que no se debe ejecutar cuando se produce una excepción). Lo mismo ocurre con todos los demás cambios posibles en el manejo de excepciones (por ejemplo, reemplazar -> volver a tirar, tragar -> envolver).

Por lo tanto, para mí, la conclusión es que el bloque de manejo de excepciones resuelve problemas que realmente no existen en la práctica. El registro de excepción y el bit de notificación están bien, pero ¿no es todo lo demás simplemente un ejemplo perfecto para la sobreingeniería?

+0

Buena pregunta. +1. También se agregaron argumentos para "excepción eliminar ubicación" en http://stackoverflow.com/questions/438073#438230. ¿Podrías echarle un vistazo? – VonC

Respuesta

12

Si usa excepciones para el flujo de control, entonces querrá mantenerse alejado del manejo de excepciones basado en políticas.

Pero en el caso de excepciones que desea tratar como no recuperables (una tarea de fondo falló, el socket se desconectó, el archivo se eliminó, etc.), es posible que desee tener una excepción configurable y basada en políticas manejo.

Por ejemplo, si está desarrollando una API, puede desear que todas las funciones de su API arrojen solo las excepciones estándar (ArgumentException, etc.), así como su propia excepción específica de biblioteca en el caso de una excepción interna no estándar (por ejemplo, un MyLibraryException). En este tipo de caso, todo lo que importa es que algo no funcionó correctamente. No está desglosando la excepción y averiguando qué salió mal. Simplemente está reconociendo el hecho de que algo algo salió mal, y que se supone que debe hacer algo ahora.

Eso algo cosa debe ser configurable, porque en realidad no importa lo que hagas. Mostrar un cuadro de mensaje para el usuario? ¿Modal o no modal? Log la excepción? ¿Cómo desea registrar la excepción? ¿Llamar a un servicio web de registro? ¿Agregar a un archivo de registro? Escribir en el registro de eventos de Windows? Insertar una entrada en la base de datos? Insertar una entrada en dos bases de datos? Realmente no importa para el resto de su aplicación. La elección de cómo manejar una excepción es completamente ortogonal al resto de la aplicación.

(Dicho sea de paso, esto no es como yo lo enfoque configurable basado en políticas de control de excepciones. Lo haría tiende más hacia un estilo de AOP, tales como el registro de un interceptor excepción-registrador en el contenedor.)

+0

Acepto que es posible que desee configurar lo que sucederá (notificación al usuario, excepción de registro, envío de correo electrónico a soporte, etc.) antes de que su aplicación se cancele de todos modos. Pareces referirte a todo lo demás (tragar, volver a lanzar, etc.) con "flujo de control", ¿verdad? –

+0

No necesariamente, depende del software. Si trata las excepciones como recuperables, entonces las está tratando como un flujo de control. Si los está tratando como no recuperables, entonces podría estar interesado en este bloque de aplicaciones. – yfeldblum

+0

Tratar una excepción como recuperable sería algo que envíe una instrucción Update a SQL Server si falla la instrucción Insert correspondiente. Ese es el flujo de control. – yfeldblum

1

En pocas palabras: si desea un manejo de excepción diferente en su código de liberación que en su código de depuración, entonces sería útil.

+0

¿Tiene un ejemplo del mundo real para eso? ¿Vuelve a lanzar una excepción en particular en modo de depuración, pero tragarlo en versión? –

+0

Seguí buscando estos ejemplos del mundo real para demostrar su utilidad, pero sin éxito hasta el momento. –

0

En mi opinión, un valor real de usar el bloque Exception Handling comienza con una línea de código en su bloque catch:

bool rethrow = ExceptionPolicy.HandleException (por ejemplo, "Política de acceso a datos");

Una línea de código: ¿qué tan simple puede obtener? Detrás de una línea de código, la política, tal como está configurada, hace que la asignación/actualización de una política se lleve a cabo fácilmente, todo ello sin tener que volver a compilar el código fuente.

Como se mencionó, la política de excepción puede realizar muchas acciones, independientemente de lo que esté definido en su política. Ocultar la complejidad detrás de una línea de código como se muestra dentro del bloque catch, es donde veo el valor real.

Yo diría complejo, pero no demasiado ingenioso. Así que mi opinión es que se verán grandes dividendos durante el mantenimiento cuando necesite cambiar la forma en que maneja/registra las excepciones al tener la flexibilidad de cambiar la configuración fácilmente y aún tener la misma línea de código fuente.

+1

Bien, pero ¿alguna vez ha visto la necesidad de ** solo ** cambiar la propagación de excepciones (esta excepción en particular se volvió a lanzar en el pasado, vamos a envolverla en una excepción diferente y lanzar eso en el futuro) y dejar todo el código circundante sin cambios ? –

5

Me encuentro con este problema cuando estoy desarrollando funciones que no tienen ningún estado recuperable. Creo que este manejo de excepciones basado en políticas es realmente útil y garantiza que todos los demás desarrolladores que forman parte de este proyecto se adhieran realmente a un estándar para excepciones no recuperables.

Acepto los carteles anteriores, es posible que desee mantenerse alejado de las excepciones basadas en políticas si las está utilizando para el flujo de control.

3

No creo que esto termine con la ingeniería. de hecho. el hecho de que las excepciones puedan pasar a través de un controlador central ha sido algo bueno en mi trabajo. He tenido desarrolladores que comerían todas las excepciones, manejadas o no, de modo que no llegaran a la parte superior y pusieran algo alarmante frente al usuario final o estropearían gravemente un servicio/daemon cuando no se detectara.

ahora con la política podemos comenzar a iniciar sesión en cualquier momento sin tener que reiniciar o rociar innecesariamente la lógica de registro en toda la aplicación. ahora podemos ver excepciones y cosas similares sin tener que desconectar la aplicación.

una programación inteligente si me preguntas ...

+0

Respecto a los desarrolladores que comen excepciones: ¿No sería una idea mucho mejor inspeccionar su código con herramientas de análisis de código (por ejemplo, FxCop) para asegurarse de que no se traguen todo? –

+1

Sí. Sí, lo haría, pero incluso si se detecta, es difícil justificar una nueva prueba/nueva prueba de las cosas que ya están en producción. No es que no tratemos de atrapar/prevenir, pero ninguna base de código es inmune a un administrador apurado y un desarrollador dispuesto a complacerlos. – MikeJ

4

Estoy de acuerdo con la afirmación de que "el bloque de control de excepciones resuelve los problemas que realmente no existen en la práctica." He usado el bloque desde su lanzamiento y rara vez siento que estoy ganando mucho al usarlo. Bueno, tal vez un poco de dolor de cabeza. :)

Antes de comenzar, voy a admitir que me gusta la funcionalidad Exception Shielding at WCF Service Boundaries. Sin embargo, eso fue agregado bastante recientemente, no involucra codificación, solo atributos y configuración, y no es como el bloque generalmente se vende. Así es como Microsoft muestra que en http://msdn.microsoft.com/en-us/library/cc309250.aspx

alt text http://i.msdn.microsoft.com/Cc309250.05-CrossLayer(en-us,MSDN.10).gif

A mis ojos lo anterior es el control de flujo.

try 
{ 
    // Run code. 
} 
catch(DataAccessException ex) 
{ 
    bool rethrow = ExceptionPolicy.HandleException(ex, "Data Access Policy"); 
    if (rethrow) 
    { 
     throw; 
    } 
} 

Cuando se combina el aspecto de control de flujo con el código anterior no son definitivamente making wrong code look wrong. (No importa que la construcción if (rethrow) no ofrezca mucha abstracción.) Esto puede dificultar el mantenimiento para desarrolladores que no están familiarizados con las definiciones de políticas. Si se cambia el postHandlingAction en el archivo de configuración (probablemente sucederá en algún momento), probablemente la aplicación se comporte de formas inesperadas que nunca se han probado.

Quizás no me resulte objetable si el bloque no manejó el control de flujo, sino que simplemente le permitió encadenar a los manipuladores.

Pero quizás no. Yo no recuerdo haber hecho piden que:

  • añadir una nueva pieza de funcionalidad al manejar una excepción (por ejemplo, además de la tala al registro de eventos también enviar un correo electrónico En realidad, el bloque de registro puede hacer eso. por sí solo si ya estaba registrando la excepción usted mismo :) :)
  • cambie el comportamiento de manejo de excepciones (tragar, volver a lanzar o lanzar nuevo) a través de una "política" completa.

No estoy diciendo que no ocurra (¡estoy seguro de que alguien tiene una historia!); Siento que el Bloque de aplicaciones para el manejo de excepciones dificulta la comprensión y el mantenimiento de los programas, y esto generalmente supera la funcionalidad provista por el bloque.