try - que tipos de excepciones existen en c#
La excepción de.NET capturada es inesperadamente nula (6)
Vea abajo para una explicación de lo que está pasando
Tengo un problema realmente extraño donde la excepción capturada es nula.
El código usa MEF y se esfuerza por informar errores de composición. Utilizando el depurador puedo ver que se lanza la excepción (una InvalidOperationException
) pero cuando es capturada por el último bloque catch en el código a continuación, la variable ex
es nula. Esto es cierto tanto en el depurador como en la ejecución del código normalmente.
static T ResolveWithErrorHandling<T>() where T : class
{
try
{
IocContainer.Compose(Settings.Default.IocConfiguration);
return IocContainer.Resolve<T>();
}
catch (ReflectionTypeLoadException ex)
{
// ... special error reporting for ReflectionTypeLoadException
}
catch (Exception ex)
{
// ex is null - that should not be possible!
// ... general error reporting for other exception types
}
return null;
}
El código que he reemplazado con comentarios es un código realmente simple para formatear el mensaje de error. Nada extraño sucediendo allí.
Intenté modificar el código para descubrir qué efecto podría tener:
- Si elimino el primer bloque catch (
ReflectionTypeLoadException
), la excepción capturada en el bloque catch final ya no será nula. - Si capturo otro tipo de excepción en el primer bloque catch, la excepción capturada en el bloque catch final ya no es nula.
- Si agrego un bloque catch para
InvalidOperationException
como primer bloque catch, la excepción capturada en ese bloque no es nula. - Si agrego un bloque catch para
InvalidOperationException
entre los dos bloques catch, la excepción capturada en ese bloque es nula.
El proyecto utiliza Contratos de Código y el código generado por el compilador se procesa posteriormente para verificar los contratos. Lamentablemente, no he encontrado una manera de deshacerme de esto para fines de prueba sin realizar una cirugía mayor en el proyecto.
Mi solución actual es no atrapar ReflectionTypeLoadException
y en su lugar ramificar en el tipo de ex
en el controlador de excepción general.
¿Cuál podría ser la explicación de este comportamiento "imposible"? ¿Qué pasa con ReflectionTypeLoadException
catch block?
De manera vergonzosa, la excepción no es nula y no puede ser nula según el estándar C.9 15.9.5.
Sin embargo, el uso de contratos de código en un proyecto puede arruinar la visualización de variables locales en el depurador porque el código de IL generado por el compilador puede reescribirse mediante contratos de código, por lo que la IL final no está sincronizada con la información de depuración. En mi caso, la variable ex
se muestra como nula, incluso no lo es. La desafortunada naturaleza de los informes de errores que tenían lugar justo antes de la finalización de la aplicación significaba que creía que el informe de errores no se debía ex.Message
como resultado de que ex
fuera nulo y que ex.Message
arrojara una NullReferenceException
dentro de mi bloque catch. Usando el depurador pude "verificar" que ex
era nulo, excepto que en realidad no era nulo.
Mi confusión se agravó por el hecho de que un bloque catch para ReflectionTypeLoadException
parece afectar el problema de visualización del depurador.
Gracias a todos los que respondieron.
Acabo de toparme con este mismo problema. Finalmente descubrí que atrapé diferentes excepciones con el mismo nombre, como lo hiciste:
catch (ReflectionTypeLoadException ex)
{
// ...
}
catch (Exception ex)
{
// ex is not null!
// ...
}
Ambos se llaman ''ex''. Cambiar uno de los dos nombres resolvió este problema para mí, como:
catch (ReflectionTypeLoadException reflectionEx)
{
// ...
}
catch (Exception ex)
{
// ex is null - that should not be possible!
// ...
}
Corrí en el mismo problema. En mi caso, el cambio de nombre de la variable de excepción (por ejemplo, ex => ex1) me permitió detectar cualquier excepción ...
Debería comprobar si, en algún momento, el IocContainer detecta una Exception ex
throws ex.InnerException
sin comprobar si es nulo.
C # acepta felizmente throw null
, y termina en catch (Exception)
.
La excepción de hecho no es nula, es un problema con el depurador. Los contratos de código (ccrewrite) cambian los códigos de operación IL y eso perturba el depurador, porque los códigos de operación leave.s se transforman en códigos de licencia. Los dos códigos de operación tienen diferentes tamaños y las direcciones de las instrucciones cambian, es por eso que el depurador se pierde cuando los nombres de las excepciones son los mismos.
Puede usar $ exception en el depurador para solucionar el problema.
Tengo la misma situación, también. Resultó ser un error del depurador de Eclipse. (Realmente, esta situación puede ser solo el resultado del error de algún depurador).
El reinicio de Eclipse fue suficiente: la excepción de tiempo de ejecución se vuelve normal, no nula. Otros depuradores podrían no ser tan amables.
Tuve el mismo problema. La excepción era nula cuando se veía en el depurador, aunque se estaba detectando el tipo correcto de excepción, UpdateException. Pude ver la excepción abriendo el Asistente de excepciones.
Tan pronto como apagué "Perform Runtime Contract Checking" detecté excepciones que ya no son nulas. He estado usando activamente contratos de código para un año y no había visto este problema antes de comenzar a trabajar con EF 4.1 en este proyecto en particular recientemente, pero no sé si EF fue una variable de control en cuanto a excepciones detectadas que son nulas. .