捕获的.NET异常意外为空 [英] .NET exception caught is unexpectedly null

查看:157
本文介绍了捕获的.NET异常意外为空的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请参阅下面的解释:



我有一个非常奇怪的问题,捕获的异常为null。 p>

代码使用MEF并尝试报告组合错误。使用调试器,我可以看到正在抛出的异常(一个 InvalidOperationException ),但是当它被 ex variable为null。在调试器和正常执行代码时都是如此。

  static T ResolveWithErrorHandling&T;()其中T:class 
{
try
{
IocContainer.Compose(Settings.Default.IocConfiguration);
return IocContainer.Resolve< T>();
}
catch(ReflectionTypeLoadException ex)
{
// ... ReflectionTypeLoadException的特殊错误报告
}
catch(Exception ex)
{
// ex为null - 这是不可能的!
// ...其他异常类型的一般错误报告
}
返回null;
}

我用注释替换的代码是格式化错误消息的真正简单的代码。



我已经尝试修改代码,以发现可能产生的影响:




  • 如果我删除第一个catch块( ReflectionTypeLoadException ),则在最终catch块中捕获的异常不再为空。

  • 如果我在第一个catch块中捕获另一个异常类型,则最终catch块中捕获的异常不再为null。

  • 如果我为<$ c添加了一个catch块$ c> InvalidOperationException 作为第一个catch块,该块中捕获的异常不为null。

  • 如果我为添加一个catch块InvalidOperationException 在两个catch块之间,该块中捕获的异常为null。



该项目使用代码合同,编译器生成的代码经过后处理以检查合同。不幸的是,我没有想出一个方法来摆脱这个测试目的,而不对该项目进行大手术。



我目前的解决方法是无法捕获 ReflectionTypeLoadException ,而是分支在一般异常处理程序中 ex 的类型。


$ b $这个不可能的行为可以解释什么?什么是 ReflectionTypeLoadException catch块?






令人尴尬的是异常不为空,并且根据C#标准15.9.5不能为空。



但是,在项目中使用代码合同可能会弄乱调试器中局部变量的显示,因为编译器生成的IL代码可以由代码合同重写,所以最终的IL与调试信息略有不同步。在我的情况下, ex 变量显示为null,即使不是。错误报告在应用程序终止之前发生的不幸性质意味着我认为错误报告由于 ex 为null而不被调用,而$ code > ex.Message 在我的catch块中抛出一个 NullReferenceException 。使用调试器,我能够验证 ex 是null,除了它实际上不为空。



我的困惑更加复杂,因为 ReflectionTypeLoadException 的catch块似乎会影响调试器显示问题。



谢谢所有回复的人。

解决方案

刚刚遇到同样的问题。我终于发现我使用相同的名字捕获了不同的异常,就像你一样:

  catch(ReflectionTypeLoadException ex)
{
// ...
}
catch(Exception ex)
{
// ex is not null!
// ...
}

两者都命名为'ex'。更改两个名称之一为我解决了这个问题,如:

  catch(ReflectionTypeLoadException reflectionEx)
{
// ...
}
catch(Exception ex)
{
// ex为null - 这是不可能的!
// ...
}


See below for an explanation of what is going on

I have a really weird issue where the exception caught is null.

The code uses MEF and tries hard to report composition errors. Using the debugger I can see the exception being thrown (an InvalidOperationException) but when it is caught by the last catch block in the code below the ex variable is null. This is true both in the debugger and when executing the code normally.

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;
}

The code I have replaced with comments is really simple code to format the error message. Nothing strange going on there.

I have tried to alter the code to discover what effect that might have:

  • If I remove the first catch block (ReflectionTypeLoadException) the exception caught in the final catch block is no longer null.
  • If I catch another exception type in the first catch block the exception caught in the final catch block is no longer null.
  • If I add a catch block for InvalidOperationException as the first catch block the exception caught in that block is not null.
  • If I add a catch block for InvalidOperationException between the two catch blocks the exception caught in that block is null.

The project uses Code Contracts and the code generated by the compiler is post-processed to check the contracts. Unfortunately, I havn't figured out a way to get rid of this for testing purposes without performing major surgery on the project.

My current workaround is to not catch ReflectionTypeLoadException and instead branch on the type of ex in the general exception handler.

What could be the explanation for this "impossible" behavior? What is up with ReflectionTypeLoadException catch block?


Embarrassingly the exception is not null and it cannot be null per the C# standard 15.9.5.

However, using Code Contracts in a project can mess up the display of local variables in the debugger because the IL code generated by the compiler can be rewritten by Code Contracts so the final IL is slightly out of sync with the debug information. In my case the ex variable is displayed as null even it is not. The unfortunate nature of the error reporting taking place right before application termination meant that I believed the error reporting to not be called as a result of ex being null and ex.Message throwing a NullReferenceException inside my catch block. Using the debugger I was able to "verify" that ex was null, except it was actually not null.

My confusion was compounded by the fact that a catch block for ReflectionTypeLoadException seems to affect the debugger display issue.

Thanks to all who responded.

解决方案

Just ran into this same problem. I finally found out that I catched different exceptions with the same name, like you did:

catch (ReflectionTypeLoadException ex)
{
    // ... 
}
catch (Exception ex)
{
    // ex is not null!
    // ...
}

Both are named 'ex'. Changing one of both names solved this problem for me, like:

catch (ReflectionTypeLoadException reflectionEx)
{
    // ... 
}
catch (Exception ex)
{
    // ex is null - that should not be possible!
    // ...
}

这篇关于捕获的.NET异常意外为空的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆