Click here to Skip to main content
15,891,607 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace throwMyDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            RaiseExcption r = new RaiseExcption();
            try
            {
               r.Without();
            }
            catch(MyException ex1)
            {
                Console.WriteLine(ex1.Message);
                Console.WriteLine(ex1.StackTrace);
                Console.Read();
            }
            try
            {

             
                r.With();
            }
            catch (MyException ex2)
            {
                Console.WriteLine(ex2.Message);
                Console.WriteLine(ex2.StackTrace);
                Console.Read();
                Console.Read();
            }
        }
    }
    class MyException : Exception
    {
        public MyException():base()
    {
    }

    }
    class RaiseExcption
    {
        public void Without()
        {
            try
            {
                throw new MyException();
            }
            catch (MyException me)
            {
                throw;
            }
        }
        public void With()
        {
            try
            {
                throw new MyException();
            }
            catch (MyException me)
            {
                throw me;
            }
        }
    }
}

I wrote this code to test the difference between throw and throw ex but unfortunately it is not working. I mean to say that the stack trace for both with and without is pointing the error location as throw statment instead of pointing the exact error location where the exception was thrown ie throw new MyException() "Can any one help me with this. Thanks in advance
Posted
Updated 27-Feb-18 22:42pm
v4
Comments
Alan N 3-Dec-11 8:26am    
I've fixed the code formatting and now you need to edit the question and tell us what "not working" means. What were the expected and actual outputs of the program?
puja11191 3-Dec-11 22:51pm    
Hi Alan, thanks for the code formatting. Actually when i m running the code the stack trace for both With() and Without() is showing the same output. But as per my expectation when we use throw it should show the exact point in the application where the error occurred. Please get back to me for more clarification on the question. Thanks in advance
[no name] 4-Dec-11 20:45pm    
EDIT: added code block

When you use the throw with an empty parameter, you are re-throwing the last exception. When you throw the existing exception you are creating a new exception.

What's the difference? Simple: the stack trace.
The empty parameter re-throw and keeps the existing stack list, the parametered version creates a new stack trace to the point of the throw. For debugging, the empty version tells you where the error actually occurred, the parametered version discards that.
 
Share this answer
 
v2
Comments
Abhinav S 3-Dec-11 8:53am    
5. Great answer.
[no name] 3-Dec-11 21:29pm    
my 5!
puja11191 3-Dec-11 22:55pm    
Hi, Thanks for the answer but the stack trace for both with and without is giving the same value. But as far as i know when we say throw it should point to the exact location in the code where the error occurred
Monjurul Habib 4-Dec-11 15:14pm    
my 5!
I was unaware of this behaviour and find it quite suprising. It certainly looks as if throw is behaving incorrectly but it isn't and we can see that more clearly if we move the exception source and the catch-rethrow into different methods.

It is important to understand that the line number reported in a stack frame is the point where control leaves the method and this may not be the point where the exception was first thrown. In the special case of catch-rethrow the stack frame line number corresponds to the position of the rethrow and this happens for both throw and throw ex.

Here is simple program that demonstrates the way that line numbers can change within the stack frame.

C#
class Program {
  static void Main(string[] args) {
    Console.BufferWidth = 160;

    Console.WriteLine("Indirect call of BadMethod with no rethrows");
    Console.WriteLine("*******************************************");
    try {
#line 100
      PassThrough();
#line default
    } catch (Exception e) {
      Console.WriteLine(e);
    }
    Console.WriteLine();

    Console.WriteLine("Indirect call of BadMethod with rethrow");
    Console.WriteLine("***************************************");
    try {
#line 200
      WithRethrow();
#line default
    } catch (Exception e) {
      Console.WriteLine(e);
    }
    Console.WriteLine();
    Console.Read();
  }

  public static void PassThrough() {
#line 1000
    BadMethod();
#line default
  }

  public static void WithRethrow() {
    try {
#line 2000
      BadMethod();
    } catch (Exception e) {
      Console.WriteLine(e);
      throw;
    }
#line default
  }

  public static void BadMethod() {
#line 3000
    throw new Exception("\"MSG: Good method gone bad\"");
#line default
  }
}

The strange #line directives alter the line numbers saved in debug information and give us simple numbers in the stack traces. This was done to make discussion of the results easier.

There are two cases and in the both we call the exception throwing BadMethod() via an intermediary, either PassThrough() which does nothing or WithRethrow() which does what the name suggests.

Indirect call of BadMethod with no rethrows
*******************************************
System.Exception: "MSG: Good method gone bad"
   at BadMethod()          line 3000
   at PassThrough()        line 1000
   at Main(String[] args)  line 100

Indirect call of BadMethod with rethrow
***************************************
System.Exception: "MSG: Good method gone bad"
   at BadMethod()          line 3000
   at WithRethrow()        line 2000
System.Exception: "MSG: Good method gone bad"
   at BadMethod()          line 3000
   at WithRethrow()        line 2003
   at Main(String[] args)  line 200


If you can imagine an exception passing through a method in the search for a matching catch block then in PassThrough() the exception enters and leaves at the same line number (1000) and this is reported in the stack frame.

In the WithRethrow() method the exception enters at line 2000 but leaves at line 2003 after being caught and rethrown. Comparison of the stack trace obtained within WithRethrow() with that from Main() clearly show the change of reported line number.

This is exactly analogous to the situation that you originally described, i.e.
C#
public void WTFMethod() {
  try {
    throw new Exception();
  } catch {
    throw;
  }
}


The exception is thrown, caught and then rethrown and the stack frame reports the point where control left the method. So although it looks very odd not to get the correct location for the exception, the behaviour for a catch and rethrow is completely consistent through the whole call stack.

Alan.
 
Share this answer
 
v2

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900