Не удается поймать исключение, выданное Invoke для скомпилированного выражения - PullRequest
2 голосов
/ 26 февраля 2010

В классе:

private Func<T, object> pony;

В моей функции:

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

Я ожидаю получить исключения, когда выкину их, но я получаю DivideByZeroException в строке newValue = pony.Invoke(model as T);. Почему это? Могу ли я что-нибудь с этим сделать?

В настоящее время это mvc2-приложение asp.net, работающее в Кассини.

Если я выберу Начать отладку в Visual Studio 2008, ошибка будет перехвачена с дополнительной информацией!

Проблема заключалась в том, что я, очевидно, не понимал, как работают внутренние исключения. Возникает исключение, но затем отображается только внутреннее исключение, и это совсем другая проблема.

Ответы [ 3 ]

1 голос
/ 26 февраля 2010

Следующий код работал для меня (это в консольном приложении 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);
    }
}

Это выводит содержимое исключения в командную строку, как и ожидалось.

1 голос
/ 26 февраля 2010

Исключения, сгенерированные из скомпилированного выражения, обычно обрабатываются конструкцией try .. catch, поэтому я ожидаю, что в вашем коде есть другая проблема. Если вы попробуете, например, следующий код, он будет работать как положено:

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

Как примечание, вы, вероятно, должны обработать DivideByZeroException, используя отдельный catch (как я делал в моем примере). Это более чистый и рекомендуемый способ отловить различные типы исключений.

Можете ли вы проверить, действительно ли исключение обрабатывается при запуске приложения без отладки (например, путем добавления отладочной печати в блок catch)? Какое исключение выводится при запуске приложения (в конце концов, ваш код перебрасывает какое-то исключение в любом случае, поэтому вывод может быть неясным).

0 голосов
/ 26 февраля 2010

Ну, код, выполняемый в скомпилированном выражении, очевидно, генерирует исключение DivideByZeroException, верно. В этом что-то пытается разделить на ноль. Так что еще вы ожидаете?

Обратите внимание, что отладчик (особенно VS) может работать с ошибками при исключениях, так что вам следует убедиться, что приложение продолжено, оно отлично доходит до блока catch.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...