Question

The following is my code in C#:

catch(Exception ex)
{
   ex.Data.Add("VarName", "object");
   throw;
}

Question: doing above, am I going to lose the entry I am adding to Data dictionary? -->as in my opinion, I am rethrowing the exception caught in the catch statement, and it does not have the added Dictionary record from the next line yet.

Should above code instead be:

catch(Exception ex)
{
   ex.Data.Add("VarName", "object");
   throw ex;
}
  • but in this case, I don't want to reset the stack trace.

Searched this all over the web and on SO, but no luck.

TIA!

Was it helpful?

Solution

Your initial code should work just fine. You should not lose the dictionary entry.

[EDIT]: Elaboration.

Let's take the following example code:

using System;
class Program
{
    static void Main()
    {
        Change();
        Replace();
        Inner();
    }

    static void Change()
    {
        try {
            try {
                throw new Exception("This is a message");
            } catch (Exception e) {
                e.Data.Add("foo", "bar");
                throw;
            }
        } catch (Exception e) {
            System.Diagnostics.Trace.WriteLine(e.Message);
            System.Diagnostics.Trace.WriteLine(e.Data["foo"]);
        }
    }

    static void Replace()
    {
        try {
            try {
                throw new Exception("This is a message");
            } catch (Exception e) {
                e = new Exception("Different message", e);
                e.Data.Add("foo", "bar");
                throw;
            }
        } catch (Exception e) {
            System.Diagnostics.Trace.WriteLine(e.Message);
            System.Diagnostics.Trace.WriteLine(e.Data["foo"]);
        }
    }

    static void Inner()
    {
        try {
            try {
                throw new Exception("This is a message");
            } catch (Exception e) {
                e.Data.Add("foo1", "bar1");
                e = new Exception("Different message", e);
                e.Data.Add("foo2", "bar2");
                throw e;
            }
        } catch (Exception e) {
            System.Diagnostics.Trace.WriteLine(e.Message);
            System.Diagnostics.Trace.WriteLine(e.Data["foo2"]);
            System.Diagnostics.Trace.WriteLine(e.InnerException.Message);
            System.Diagnostics.Trace.WriteLine(e.InnerException.Data["foo1"]);
        }
    }
}

When throwing an Exception, what is really thrown is a reference to an Exception object. That reference is what is caught and rethrown. Modifying the underlying object is fine. This is what your initial code does, and what the Change method in my example does.

In the Replace method we modify not the object, but the reference itself. We make it point to a brand new Exception object with a different message and to top it off we also add some data. All this stuff is lost, though, because throw without arguments rethrows the original reference.

Should the need arise to use the second case, you can keep track of your stack trace by including the original exception as InnerException, like I did in the Inner method.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top