Как получить имя метода, вызвавшего исключение - PullRequest
17 голосов
/ 04 января 2011

Мой код выглядит как показано ниже.

try
{
    _productRepo.GetAllProductCategories();
}
catch (Exception ex)
{
    //Do Something
}

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

Ответы [ 3 ]

21 голосов
/ 04 января 2011

На System.Exception есть свойство TargetSite, которое должно пригодиться.

Получает метод, который вызывает текущее исключение.

В вашем случае вы, вероятно, захотите что-то вроде:

catch (Exception ex)
{
   MethodBase site = ex.TargetSite;
   string methodName = site == null ? null : site.Name;
   ...           
}

Стоит указать на некоторые из перечисленных проблем:

Если метод, которыйвыбрасывает это исключение недоступно и трассировка стека не является пустой ссылкой (Nothing в Visual Basic), TargetSite получает метод из трассировки стека.Если трассировка стека является пустой ссылкой, TargetSite также возвращает пустую ссылку.

Примечание. Свойство TargetSite может не точно содержать имя метода, в котором было сгенерировано исключение, если обработчик исключения обрабатывает исключение вграницы области приложения.

Вы можете использовать свойство StackTrace, как подсказывает @leppie, но учтите, что это строковое представление фреймов в стеке;поэтому вам придется манипулировать, если вам нужно только имя метода, вызвавшего исключение.

3 голосов
/ 05 января 2011

Это в StackFrame ...

private string GetExecutingMethodName()
{
    string result = "Unknown";
    StackTrace trace = new StackTrace(false);
    Type type = this.GetType();

    for (int index = 0; index < trace.FrameCount; ++index)
    {
        StackFrame frame = trace.GetFrame(index);
        MethodBase method = frame.GetMethod();

        if (method.DeclaringType != type && !type.IsAssignableFrom(method.DeclaringType))
        {
            result = string.Concat(method.DeclaringType.FullName, ".", method.Name);
            break;
        }
    }

    return result;
}

Этот метод был написан для класса обработчика Logging, и использование GetType () просто исключает возвращение методов в классе обработчика Logging в качестве последнего выполняемого метода. Поскольку класс обработчика Logging был написан не только для регистрации исключений, потребовался новый объект StackTrace. Очевидно, что для поиска «метода, вызвавшего исключение», GetType () может не понадобиться.

Если вам просто нужна вершина стека, возьмите первый кадр, вызовите GetMethod () и верните его или просто используйте TargetSite. GetType () может быть удален. Также обратите внимание, что исключение нужно будет передать для создания объекта StackTrace. Например:

class Program
{
    static void Main(string[] args)
    {
        try
        {
            Test();
        }
        catch (Exception ex)
        {

            // does not work properly - writes "Main"
            Console.WriteLine(MethodBase.GetCurrentMethod());

            // properly writes "TestConsole.Program.Test"
            Console.WriteLine(GetExecutingMethodName(ex));

            // properly writes "Test"
            Console.WriteLine(ex.TargetSite.Name);
        }

        Console.ReadKey();
    }


    static void Test()
    {
        throw new Exception("test");
    }

    private static string GetExecutingMethodName(Exception exception)
    {
        var trace = new StackTrace(exception);
        var frame = trace.GetFrame(0);
        var method = frame.GetMethod();

        return string.Concat(method.DeclaringType.FullName, ".", method.Name);
    }
}

По сути, если TargetSite () делает то, что вы хотите, тогда не идите дальше. Но часто в обработчиках ведения журнала объект исключения недоступен (т.е. отслеживание и аудит), поэтому новый объект StackTrace () необходим для извлечения последнего выполненного метода, который был ДО ДО метода ведения журнала.

1 голос
/ 04 января 2011

Посмотрите на трассировку стека.

Это свойство исключения.

...