简体   繁体   中英

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!

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

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

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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