rethrow for debugging
A question came up on an internal email list.
You will get this error in the following code, as per the rules of C#:
try
{
....
}
catch(Exception e)
{
// Handle cleanup.
throw;
}
With the exception of disabling this specific warning, is there anyway to have the Exception variable in a catch that is not using it (so that debugging is easier) and not hit this warning?
Can the warning be disabled only for catch()? (Yeah, I am guessing it can't too, worth asking. :))
The goal is to make it easy to set a breakpoint here & see the details of the exception, without interfering with the behavior of the program. ‘throw e’ is different from ‘throw’ here.
One proposal was to throw a new exception, with ‘e’ as the inner exception. The proposal relied too much on strings for my taste, so I put this together:
using System;
using System.Runtime.Serialization;
[Serializable]
public class RethrownException : ApplicationException
{
public static void Throw(Exception exception)
{
throw new RethrownException(exception);
}
public RethrownException(Exception inner) : base(null, inner) { }
public RethrownException(SerializationInfo info, StreamingContext context) : base(info, context) { }
}
And here’s the usage:
try
{
throw new System.Exception("sdfs");
}
catch (System.Exception ex)
{
RethrownException.Throw(ex);
}
What do you think?
Comments
- Anonymous
May 21, 2004
Doesn't the debugger in 2003 have a special local value called $exception that contains the thrown exception? - Anonymous
May 21, 2004
It seems that the recommendation from the CLR team these days is avoid deriving from ApplicationException...
http://blogs.msdn.com/brada/archive/2004/03/25/96251.aspx - Anonymous
May 21, 2004
I don't like the wrap and rethrow idea. You are not adding any useful information to the original exception, just making things unnecessarily complicated.
The original code should just use try/finally. - Anonymous
May 21, 2004
When you rethrow this way, you restart the stack trace and therefore lose the context of the original exception. - Anonymous
May 21, 2004
you should just
try {
}
catch {
throw;
} - Anonymous
May 21, 2004
Why get rid of the warning? You have $exception and if you still want the ex variable for debugging, the warning is a friendly reminder to get rid of it later on. - Anonymous
May 21, 2004
If there is important information in that method you may want to tracing it out somehow so you can debug the problem in release builds and on non-dev machines too.
I keep hearing about $exception....how does that work. How do you access it? - Anonymous
May 22, 2004
Josh: The guidelines are a bit mixed up. It depends on where you read.
I'll have to research it more. We now generate exception implementations for you, so we better get it right! - Anonymous
May 22, 2004
The comment has been removed - Anonymous
May 22, 2004
catch(Exception e){
Debug.WriteLine( e ); // eliminated in release builds
throw;
} - Anonymous
May 22, 2004
Another option is:
catch (Exception e)
{
Exception temp = e;
throw;
} - Anonymous
May 22, 2004
I'm lazy, I don't like setting breakpoints here and there - if there's an exception, I want to be there automatically. So what we did was creating a base exception in our companies base class library, whe each constructor is doing an Assert. Each caught "System.Exception" is rethrown, packed into our base Exception (we use the FxCop Rules). If there's an exception, Assert will tell me and bring me to the right spot.
One big disadvantage is that sometimes there are many many Asserts. Thus, to handle "expected" Asserts, we implemented a configurable exception-suppression-mechanism. - Anonymous
May 24, 2004
Of course, the base code pattern you're using here will be flagged as problematic by FxCop: one should stay away from catch-all (catching System.Exception) error handling. - Anonymous
May 24, 2004
Triton is right on that one.