2011-08-22 24 views
15

Tengo una aplicación que ejecuta un proceso por lotes largo donde podrían lanzarse muchas excepciones. Si se lanza una excepción no crítica durante un artículo en el lote, simplemente quiero iniciar sesión y continuar, para poder solucionar el problema más tarde y dejar que los otros elementos del lote continúen.¿Qué excepciones no debería detectar?

Algunas excepciones, como OutOfMemoryException, son devastadoras para la aplicación como un todo, y estas me gustaría volver a lanzarlas para que se conviertan en manejador de excepción global que registrará el error y detendrá la aplicación.

Así que mi pregunta es, ¿hay una lista razonablemente breve de excepciones críticas que puedo volver a lanzar en mi controlador de excepciones más bajo mientras suprimo (después de iniciar sesión) todo lo demás?

Gracias!

Editar: Elaborar un poco, aquí es la estructura básica de mi programa

foreach(var item in longItemList) 
{ 
    try 
    { 
     bigDynamicDispatchMethod(item); 
    } 
    catch(Exception ex) 
    { 
     logException(ex); 
    } 
}

hay potencialmente un gran número de excepciones que puedan ser lanzados porque este circuito es más o menos en el nivel superior de mi aplicación. El 99% del código en mi proyecto está detrás del método de envío. Hago un manejo de excepciones razonable en niveles más bajos, pero los errores aún se abren paso y no quiero detener otros procesos no relacionados en el lote después de que se lanza una excepción.

Tratando de encontrar qué excepciones podrían arrojarse en cualquier otro lugar en mi aplicación parece una tarea desalentadora, y parecía ser que sería más simple obtener una lista negra de excepciones críticas.

¿Existe alguna forma mejor de estructurar mi aplicación para hacer frente a esto? Estoy abierto a sugerencias.

+0

posible duplicado de [¿Qué tipos de excepción no para coger?] (http://stackoverflow.com/questions/5507836/which-types- of-exception-not-to-catch) –

Respuesta

24

No necesita una lista de excepciones 'incorrectas', debe tratar todo como malo de manera predeterminada. Solo atrapa lo que puedes manejar y recuperarte. CLR cannotify usted de excepciones no controladas para que pueda iniciar sesión correctamente. Tragar todo excepto las excepciones en la lista negra no es una forma adecuada de corregir sus errores. Eso solo los enmascararía. Lea this y this.

no se excluya a excepciones especiales al coger con el propósito de transferir excepciones.

En lugar de crear listas de excepciones especiales en sus cláusulas catch, debe coger únicamente las excepciones que pueda legítimamente mango. Las excepciones que no puede manejar no se deben tratar como casos especiales en manejadores de excepciones no específicos. El siguiente ejemplo de código muestra pruebas incorrectas para excepciones especiales con el objetivo de volver a lanzarlas.

public class BadExceptionHandlingExample2 { 
    public void DoWork() { 
     // Do some work that might throw exceptions. 
    } 
    public void MethodWithBadHandler() { 
     try { 
      DoWork(); 
     } catch (Exception e) { 
      if (e is StackOverflowException || 
       e is OutOfMemoryException) 
       throw; 
      // Handle the exception and 
      // continue executing. 
     } 
    } 
} 

Pocas otras reglas:

evitar la manipulación de errores por la captura de excepciones no específicos, tales como System.Exception, System.SystemException, y así sucesivamente, en aplicación de código . Hay casos en que se aceptan errores de manejo en las aplicaciones , pero estos casos son raros.

Una aplicación no debe manejar excepciones que pueden dar lugar a un estado inesperado o explotable . Si no puede predecir todas las posibles causas de una excepción y asegúrese de que el código malicioso no pueda explotar el estado de la aplicación resultante, debe permitir que la aplicación a finalice en lugar de manejar la excepción.

Considere la posibilidad de detectar excepciones específicas cuando comprenda por qué se lanzará en un contexto determinado.

Debe ver solo las excepciones de las que puede recuperar. Para el ejemplo , una aplicación puede manejar una excepción FileNotFoundException que es resultado de un intento de abrir un archivo inexistente porque puede comunicar el problema al usuario y permitirle especificar un nombre de archivo diferente o crear el archivo . No se debe gestionar una solicitud para abrir un archivo que genera ExecutionEngineException porque no se puede conocer la causa subyacente de la excepción con cualquier grado de certeza, y la aplicación no puede garantizar que es seguro continuar la ejecución.

Eric Lippert clasifica todas las excepciones en 4 grupos: Fatal, 'Boneheaded', Vexing, Exógeno. Lo que sigue es mi interpretación de los consejos de Eric:

Exc. type | What to do       | Example 
------------|-------------------------------------|------------------- 
Fatal  | nothing, let CLR handle it   | OutOfMemoryException 
------------|-------------------------------------|------------------- 
Boneheaded | fix the bug that caused exception | ArgumentNullException 
------------|-------------------------------------|------------------- 
Vexing  | fix the bug that caused exception | FormatException from 
      | (by catching exception because  | Guid constructor 
      | the framework provides no other way | (fixed in .NET 4.0 
      | way of handling). Open MS Connect | by Guid.TryParse) 
      | issue.        | 
------------|-------------------------------------|------------------- 
Exogenous | handle exception programmatically | FileNotFoundException 

Esto es aproximadamente equivalente a Microsoft's categorización: Uso, Error de programa y el fracaso del sistema. También puede usar herramientas de análisis estático como FxCop para hacer cumplir some de estas reglas.

+3

También puede manejar excepciones molestas. Son irritantes porque * debes * manejarlos en la mayoría de las situaciones. –

+0

@Eric: He actualizado la respuesta con mi interpretación del artículo, espero haberlo hecho bien. – Dmitry

+2

¡Luce increíble! ___ –

11

No capte ninguna excepción que no sepa cómo manejar con seguridad.

La captura de Exception es una práctica particularmente mala, la única peor es un catch que no especifica ningún tipo de excepción administrada (ya que también atraparía excepciones no administradas).

+0

.NET 2.0 ajustará automáticamente las excepciones que no cumplen con CLS (es decir, cualquier excepción cuya clase no herede de Exception) a s RuntimeWrappedException al presentarlos para capturar bloques en código compatible con CLS; así que realmente no hay ninguna razón para usar bloques catch sin parámetros. –

+0

Sigo este consejo en la mayoría de los casos, pero este es un caso especial. Ver editar. –

1

Un diseño más adecuado sería compatible con la pregunta: Which exceptionsdebería ¿Captura?

Si realmente necesita detectar cualquiera y todas las excepciones y seguir funcionando, entonces debe utilizar tanto AppDomain sy separar los procesos de trabajo. O cambie su host a ASP.NET o al planificador de tareas, que ya han hecho todo el trabajo duro alrededor del aislamiento y reintentos del proceso.

+0

Gracias por esto, esto es algo a mirar. –

1

A menos que aplique el atributo HandleProcessCorruptedStateExceptions a una función de manejo de excepciones, todas las excepciones 'no deberían ser manejadas por el código de usuario' ya están ignoradas para que pueda manejar cualquier cosa que no sea corromper las excepciones de forma segura.

1

Me referiré al consejo del siguiente artículo.

.NET diseño de la estructura directrices reglas: no debe quedar atrapado excepciones que Usted no puede manejar

http://www.codeproject.com/KB/cs/csmverrorhandling.aspx

Además del artículo de referencia:

Nunca se debe coger System.Exception o en System.SystemException un bloque catch

1

Captura los errores que esperas que arroje tu código. . Cuando cada vez que está utilizando una API o un método de ver qué excepciones se va a tirar y coger sólo los .. No deberías hacer una lista f excepciones y siempre atrapar a los ..

  • leer desde el manejo de excepciones MSDN Google mejores prácticas
  • Nunca coger ingenio las excepciones no específicos como excepción
Cuestiones relacionadas