开发者

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);. Why is this? Can I do something about it?

This is in a asp.net mvc2-application running in Cassini at the moment.

If I select Start debugging in Visual Studio 2008, the error gets caught and rethrown with the extra information!

开发者_JAVA百科

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.


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. 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). 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)? 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).


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):

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.


Well, the code executed in the compiled expression obviously generates the DivideByZeroException, right. 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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜