Как получить имя метода, вызвавшего исключение

Мой код выглядит следующим образом.

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

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

Ответ 1

В System.Exception должно быть полезно TargetSite свойство.

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

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

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

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

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

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

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

Ответ 2

Это в 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;
}

Этот метод был написан для класса обработчика ведения журнала, а использование GetType() просто исключает методы в классе обработчика ведения журнала, которые возвращаются в качестве последнего метода выполнения. Поскольку класс обработчика ведения журнала был написан для более чем просто регистрации исключений, потребовался новый объект 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(), который предшествует методу ведения журнала.

Ответ 3

Посмотрите на stacktrace.

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