次の方法で共有


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.