.net - How to change exception message of Exception object?

i found the solution in a blog post linked from a news site:

catch (Exception e)
{
   Exception e2 = (Exception)Activator.CreateInstance(e.GetType(), message, e);
   throw e2;
}

It's not perfect (you lose your stack trace); but that's the nature of .NET.


I just wanted to chime in here for Ian related to his answer. If you use the technique in the blog post you won't lose the stack. Yes, you will lose the stack in the member of StackTrace of the final exception, but you won't lose the stack overall because of the inner exceptions. Look here:

class Program
{
    static void Main(string[] args)
    {
        try
        {
            Test1();
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex);
        }
    }

    public static void Test1()
    {
        try
        {
            Test2();
        }
        catch (Exception ex)
        {
            throw ExceptionUtil.Rethrow(ex, "caught in test1");
        }
    }

    public static void Test2()
    {
        throw new Exception("test2");
    }

    public static class ExceptionUtil
    {
        public static Exception Rethrow(Exception ex, string message)
        {
            if (ex == null)
            {
                ex = new Exception("Error rethrowing exception because original exception is <null>.");
            }

            Exception rethrow;

            try
            {
                rethrow = (Exception)Activator.CreateInstance(ex.GetType(), message, ex);
            }
            catch (Exception)
            {
                rethrow = new Exception(message, ex);
            }
            return rethrow;
        }

        public static Exception Rethrow(Exception ex, string message, params object[] args)
        {
            string formatted;

            try
            {
                formatted = String.Format(message, args);
            }
            catch (Exception ex2)
            {
                formatted = message + "\r\n\r\nAn error occurred filling in exception message details:\r\n\r\n" + ex2;
            }
            return Rethrow(ex, formatted);
        }
    }

}

If you take the exception's full string you'll get:

System.Exception: caught in test1 ---> System.Exception: test2
at ScratchPad2.Program.Test2() in C:\Projects\Experiments\ScratchPad2\Program.cs:line 36
at ScratchPad2.Program.Test1() in C:\Projects\Experiments\ScratchPad2\Program.cs:line 26
--- End of inner exception stack trace ---
at ScratchPad2.Program.Test1() in C:\Projects\Experiments\ScratchPad2\Program.cs:line 30
at ScratchPad2.Program.Main(String[] args) in C:\Projects\Experiments\ScratchPad2\Program.cs:line 14

So you got the whole stack anyways, plus extra information


You can wrap the previous exception in a new one with your new message and make use of the inner exception for the stack trace/etc.

try
{
    throw new Exception("This error message sucks");
}
catch (Exception e)
{
    throw new Exception("There error message is prettier", e);
}

You create a new Exception (or – better – specific subtype) that has the new message (and pass the original exception as InnerException).

Eg.

throw new MyExceptionType("Some interesting message", originalException);

NB. If you really want to use Activator.CreateInstance you can use an overload that can be passed parameters, but different Exception derived types cannot be relied on to have an constructor overload for (message, innerException).

Tags:

.Net

Exception