views:

90

answers:

3

If you wrap a call to HttpResponse.End within a try catch block, the ThreadAbortException would automatically be re-raised. I assume this is the case even if you wrap the try catch block in a try catch block.

How can I accomplish the same thing? I do not have a real-world application for this.

namespace Program
{
    class ReJoice
    {
        public void End() //This does not automatically re-raise the exception if caught.  
        {
            throw new Exception();
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                ReJoice x = new ReJoice();
                x.End();
            }
            catch (Exception e) {}
        }
    }
}
+1  A: 

You mean like this?

namespace Program
{
    class ReJoice
    {
        public void End() //This does not automatically re-raise the exception if caught.  
        {
            throw new Exception();
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                ReJoice x = new ReJoice();
                x.End();
            }
            catch (Exception e) {
               throw e;
            }
        }
    }
}

Edit: It doesn't re-raise the exception because the meaning of "catch" is to handle the exception. It is up to you as the caller of x.End() what you want to do when an exception occurs. By catching the exception and doing nothing you are saying that you want to ignore the exception. Within the catch block you can display a message box, or log the error, kill the application entirely, or rethrow the error with additional information by wrapping the exception:

throw new Exception("New message", e);
AaronLS
"throw e" will limit your exception trace to this line.
Gregoire
@Greg - ditto. never explicitly throw an exception that you did not create. `catch{throw;}` would be more appropriate.
Sky Sanders
@Greg Then just `throw` if you want. He didn't specify that in his requirements. Don't downvote me because his requirements are vague!
AaronLS
@Sky There are scenarios that for security reasons you don't want to expose the entire stack trace to the consuming code. I didn't see this as a place to get into the fine details of when to throw or wrap the exception or reset the stack trace. There are valid reasons for each scenario and that is an entirely different discussion to itself.
AaronLS
@AaronLS: I haven't downvoted you
Gregoire
@Greg I realized that. There are merits to each approach depending on the scenario and where in the framework this is occurring. From the example and requirements he gave I have no way of knowing which approach would be best for him. He even stated himself he has no practical application in mind. You are narrow minded to think in such a small box and try to apply a one-size-fits-all approach.
AaronLS
You are absolutely right. I was just adding some depth, as this, taken at it's face, is the most common abuse of structured exception handling. Less seasoned devs see this pattern and repeat it by wrote without a clear understanding. Perhaps this dialog can draw attention to it.
Sky Sanders
@Greg I apologize Greg, I shouldn't have called you narrow minded. When I read your post I thought you were saying you did downvote me, I didn't catch the "n't".
AaronLS
+3  A: 

It's as simple as using the plain throw statement.

throw;

in the relevant catch block. Note that this is advantageous over doing throw e; because it preserves the call stack at the point of the exception.

Of course, this isn't automated in perhaps the sense you want, but unfortunately that is not possible. This is pretty much the best solution you'll get, and pretty simple still I think. ThreadAbortException is special in the CLR because it is almost inherent in thread management.

In the case of your program, you'd have something like:

namespace Program
{
    class ReJoice
    {
        public void End()
        {
            throw new Exception();
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                ReJoice x = new ReJoice();
                x.End();
            }
            catch (Exception e) 
            {
                throw;
            }
        }
    }
}
Noldorin
I think he wants to make it so that the exception automatically is rethrown even if you don't do that, like `ThreadAbortException`.
Mark Byers
@Mark: Yeah, you could be right, though I think this solution is the best he can get. The nature of `ThreadAbortException` is special, because the CLR uses it inherently when managing threads. You can't really reproduce that behaviour directly from C#.
Noldorin
+6  A: 

You can't change ordinary exceptions to have this behaviour. ThreadAbortException has special support for this that you can't implement yourself in C#.

ThreadAbortException is a special exception that can be caught, but it will automatically be raised again at the end of the catch block.

Mark Byers
Indeed, but `throw` is the practical (only slightly manual) solution.
Noldorin
Ah. I saw this line elsewhere, but misinterpreted it as meaning the special support was something I could mimic.
Brian