Reputation: 47
I'm using Ranorex a test automation tool which is based on c# and have a question re: Exception Handling and rethrowing the exception. I'm are fairly new to c# programming so please bear we me! Consider the following code:
Child Class/Method..
try
{
do something;
'unhandled exception on line 150'
}
catch (exception)
{
throw;
}
parent Class/Method
try
{
childmethod();
}
catch (exception ex)
{
report.info("Info",ex.Stacktrace);
}
What i'd like to be able to do is report the line number that the exception occured in, in the child class/method but in the Parent class exception handler. This way in every child class/method we can just rethrow (throw) the exception back up to the master class/method (i.e the test case in Ranorex terms). In the parent exception handler we have other things to do like reporting system details, closing the application and failing the test. We only want to do this in one place, hence put in the top level class. Using the code above however the stracktrace shows the line number in the child exception handler that rethrows and also the line number where the child method was called. It would also be useful if we could just extract from the stacktrace something formatted like
Class = 'class name' & Method = 'method name' & Line Num = 'line num'
rather than the whole stacktrace message.
We're using .net v4.0
Thanks for you help.
StackTrace:
The stacktrace information is: at System.Data.DataRow.GetDataColumn(String columnName)
at System.Data.DataRow.get_Item(String columnName)
at ABCTest.SUD.Plat.NewFU.NewFUUserCode.MainMethod(String testDataInstanceId) in c:\Ranorex Local Code\ABCTest\ABCTest\SUD\Plat\NewFU\NewFUUserCode.cs:line 103
at ABCTest.SUD.Plat.NewFU.NewFUUserCode.MainMethod(String testDataInstanceId) in c:\Ranorex Local Code\ABCTest\ABCTest\SUD\Plat\NewFU\NewFireFUUserCode.cs:line 130
at ABCTest.Tests.ManageFAndS.ManACA_IO_One.MainMethod() in c:\Ranorex Local Code\ABCTest\ABCTest\Tests\ManageFAndS\ManACA_IO_One.cs:line 59
Upvotes: 1
Views: 1326
Reputation: 111910
Here http://weblogs.asp.net/fmarguerie/archive/2008/01/02/rethrowing-exceptions-and-preserving-the-full-call-stack-trace.aspx there is a solution. I'm not sure I would use it in my code, because it's based on an undocumented method (but it still works in .NET 4.0)
private static void PreserveStackTrace(Exception exception)
{
MethodInfo preserveStackTrace = typeof(Exception).GetMethod("InternalPreserveStackTrace",
BindingFlags.Instance | BindingFlags.NonPublic);
preserveStackTrace.Invoke(exception, null);
}
static void MethodChild()
{
try
{
throw new ArgumentException();
}
catch (Exception ex)
{
// Very important! Do it before rethrowing
PreserveStackTrace(ex);
throw;
}
}
This response on SO explained the problem: you can't have two stack frames of the same method. One method = one stack frame.
To obtain infos on where the exception was thrown you can use the StackTrace class:
StackTrace st = new StackTrace(ex, true);
StackFrame frame = st.GetFrame(0);
MethodBase method = frame.GetMethod();
// What you want!
string methodName = method.Name;
string className = method.DeclaringType.FullName;
int lineNumber = frame.GetFileLineNumber();
passing the exception to the constructor and true
as the second parameter.
Upvotes: 0