简体   繁体   English

无法捕获Invoke在编译表达式上抛出的异常

[英]Can't catch exception thrown by Invoke on a compiled expression

In the class: 在课堂里:

private Func<T, object> pony;

In my function: 在我的功能:

object newValue;
try {
  newValue = pony.Invoke(model as T); // This is the line where I get an exception!
} catch (Exception exception) {
  // This code is never run, even though I get an exception two lines up!
  if(exception is DivideByZeroException) throw new DivideByZeroException("Division by zero when calculating member " + GetMemberName(), exception);
  throw;
}

I expect to get exceptions when I throw them, but I get a DivideByZeroException on the line newValue = pony.Invoke(model as T); 我希望在抛出它们时会出现异常,但是我在newValue = pony.Invoke(model as T);行上得到了DivideByZeroException newValue = pony.Invoke(model as T); . Why is this? 为什么是这样? Can I do something about it? 我能为此做些什么吗?

This is in a asp.net mvc2-application running in Cassini at the moment. 这是在Cassini中运行的asp.net mvc2应用程序。

If I select Start debugging in Visual Studio 2008, the error gets caught and rethrown with the extra information! 如果我在Visual Studio 2008中选择“开始调试”,则会捕获错误并使用额外信息重新生成错误!

The problem was that I obviously haven't understood how inner exceptions work. 问题是我显然不了解内部异常是如何工作的。 The exception gets caught but then only the inner exception is shown, and that's a totally other issue. 异常被捕获,但之后只显示内部异常,这是一个完全不同的问题。

The following code worked for me (this is in a C# console app, although I don't know why that would work differently from ASP.NET): 以下代码适用于我(这是在C#控制台应用程序中,虽然我不知道为什么它与ASP.NET不同):

class Program
{
    static void Main(string[] args)
    {
        var foo = new Foo<int>();
        try
        {
            Console.WriteLine("Calling function");
            foo.DoStuff(5);
        }
        catch(Exception ex)
        {
            Console.WriteLine("Caught exception: " + ex.ToString());
        }
        finally
        {
            Console.WriteLine("In finally block");
        }
    }
}

class Foo<T>
{
    private Func<T, object> pony;

    public Foo()
    {
        this.pony = m =>
        {
            throw new DivideByZeroException("Exception!");
        };
    }

    public object DoStuff(T o)
    {
        return this.pony.Invoke(o);
    }
}

This prints out the contents of the exception to the command line, as expected. 这将按预期将命令行中的异常内容打印出来。

Exceptions thrown from a compiled expression are handled normally by the try .. catch construct, so I'd expect that there is some other issue in your code. 从编译表达式抛出的异常通常由try .. catch构造处理,所以我希望你的代码中还有一些其他问题。 If you try for example the following code, it behaves as expected: 如果您尝试以下代码,它的行为符合预期:

Expression<Func<int, int>> f = x => 10 / x;
Func<int, int> fcompiled = f.Compile();
try {
  Console.WriteLine(fcompiled(0));
} catch (DivideByZeroException e) {
  Console.WriteLine("Divison by zero");
}

As a side note, you should probably handle DivideByZeroException using a separate catch (as I did in my example). 作为旁注,您应该使用单独的catch来处理DivideByZeroException (就像我在我的示例中所做的那样)。 This is a cleaner and recommended way to catch different types of exceptions. 这是一种更清晰,更推荐的方法来捕获不同类型的异常。

Can you check whether the exception is really unhandled when running the application without debugging (for example by adding some debug print to the catch block)? 在没有调试的情况下运行应用程序时是否可以检查异常是否真的未处理(例如通过向catch块添加一些调试打印)? What exception is printed when you run the application (afterall, your code rethrows some exception in any case, so the output may not be clear). 运行应用程序时会打印什么异常(毕竟,您的代码在任何情况下都会重新抛出一些异常,因此输出可能不清楚)。

Well, the code executed in the compiled expression obviously generates the DivideByZeroException, right. 好吧,在编译表达式中执行的代码显然会生成DivideByZeroException。 Something tries to divide by zero in that. 有些东西试图除以零。 So what else would you expect? 那你还期待什么呢?

Note that the debugger (especially VS) may break on exceptions, so that you should make sure to continue running the application, it should reach your catch block just fine. 请注意,调试器(尤其是VS)可能会在异常时中断,因此您应该确保继续运行应用程序,它应该很好地到达catch块。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM