1

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
Sam Harwell
  • 97,721
  • 20
  • 209
  • 280
rockOn123
  • 45
  • 1
  • 1
  • 7

1 Answers1

0

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.

Community
  • 1
  • 1
xanatos
  • 109,618
  • 12
  • 197
  • 280
  • Thanks for the info. The above info correctly gives me the method and class names, however the line number is still giving me the line number in the child exception handler where the exception is rethrown. There are 2 frames. Frame 0 is for the child method and frame 1 is for the parent method. I've put the stack trace into the original post. – rockOn123 Aug 07 '13 at 10:39
  • @TimGONELLA Have you added the `PreserveStackTrace(ex);` before each re`throw`? – xanatos Aug 07 '13 at 10:43
  • Yes, i've put it before the re 'throw' in the child exception handler. So frame o gives me line 130 and frame 1 gives me line 59. Whereas i need line 103 in the stacktrace. – rockOn123 Aug 07 '13 at 10:45
  • @TimGONELLA I see that on NET 4.5 there are other solutions: http://stackoverflow.com/a/17091351/613130 OR you could try the "manual" PreserveStackFrame http://stackoverflow.com/a/2085377/613130 (that works without using undocumented features) – xanatos Aug 07 '13 at 10:49
  • thanks @Xanatos. Unfortunately we cannot upgrade to .Net 4.5. The PreserveStackFrame is unclear to me, but i'll give it a go. – rockOn123 Aug 07 '13 at 11:21