How to get the name of the method that caused the exception
Solution 1
There's a TargetSite
property on System.Exception
that should come in handy.
Gets the method that throws the current exception.
In your case, you probably want something like:
catch (Exception ex)
{
MethodBase site = ex.TargetSite;
string methodName = site == null ? null : site.Name;
...
}
It's worth pointing out some of the issues listed:
If the method that throws this exception is not available and the stack trace is not a null reference (Nothing in Visual Basic), TargetSite obtains the method from the stack trace. If the stack trace is a null reference, TargetSite also returns a null reference.
Note: The TargetSite property may not accurately report the name of the method in which an exception was thrown if the exception handler handles an exception across application domain boundaries.
You could use the StackTrace
property as @leppie suggests too, but do note that this is a string representation of the frames on the stack; so you'll have to manipulate if you only want the name of the method that threw the execption.
Solution 2
It's in the 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;
}
This method was written for an Logging handler class and the use of GetType() simply eliminates the methods within the Logging handler class from being returned as the last executing method. Since the Logging handler class was written for more than just logging exceptions, a new StackTrace object was required. Obviously, for finding "the method that threw the exception" GetType() might not be necessary.
If you just want the top of the stack, take the first frame, call GetMethod() and return that, or simply use TargetSite. GetType() could then be removed. Also note, that the Exception would need to be passed in to create the StackTrace object. For example:
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);
}
}
Basically, if TargetSite() does what you want, then go no further. But, often times in Logging handlers, an exception object is not available (i.e. tracing and auditing) so a new StackTrace() object is necessary for retrieving the last executed method, the one BEFORE the Logging method.
Solution 3
Look at the stacktrace.
It's a property on the exception.
SKumar
Updated on July 09, 2022Comments
-
SKumar almost 2 years
My code looks as below.
try { _productRepo.GetAllProductCategories(); } catch (Exception ex) { //Do Something }
I need a way to show the method name, suppose in the above case if any exception is thrown in the GetAllProductCategories() method, I need to get this method name i.e. "GetAllProductCategories()" as my result. Can any one suggest me how to do this?
-
KingOfHypocrites almost 10 yearsWhat is GetType in reference to? Is this another method you created? The built in GetType needs an object to reference.
-
Chris Gessler almost 10 years@KingOfHypocrites - GetType() is being called from the current class.
-
Peter Duniho over 9 yearsI don't see how this applies to the question asked. This code generates a whole new
StackTrace
object, unrelated to the exception's stack trace. Also, .NET already has a perfectly good (and more reliable) way to obtain theMethodInfo
object for the currently executing method:MethodBase.GetCurrentMethod
-
Chris Gessler over 9 years@PeterDuniho - It demonstrates that the current executing method name is available from the StackFrame. So in an error condition, the Exception object can be used to create a StackTrace object which can be used to get the StackFrames. The method could be easily modified to accept an Exception object, but the code is more of a demonstration of how to use StackFrame. Also note that MethodBase.GetCurrentMethod() will only provide the name of the current method being executed, not the method that threw the exception.
-
Bjorn almost 4 years@ChrisGessler How can I get the mathod in an async method? The stacktrace is more complex and I dont see the "real" method name here.