How can I add a message to an exception without losing any information in C#?
Solution 1:
If you just need to add information to the original exception, such as a user-readable message or specific details that will be useful to you in tracking down the error but that won't be useful to the end user, you can make use of the Exception's Data property, which is a key/value pair dictionary.
We use this extensively in order to record information such as the report being executed or file that is being processed so that operations can determine what exactly was happening at the time of the error. The user doesn't need this detail since they are working directly with the cause of the failure.
You could also use this to pass a plain text message that makes sense to the user. The only issue is that you will have to perform some additional work in your logging framework or end-user interface in order to extract the data and make it useful to the consumer.
For example, you could do:
catch (Exception ex)
{
ex.Data.Add("UserMessage", "An error occurred while trying to load the XSLT file.");
throw;
}
Then in the client-side code, you could test to see if UserMessage exists and, if so, present it to the user instead of the Exception:
catch (Exception ex)
{
if (ex.Data.Contains("UserMessage"))
{
MessageBox.Show(ex.Data["UserMessage"].ToString());
}
else
{
MessageBox.Show(ex.Message);
}
}
Solution 2:
That original Exception is still there.
When you do your Exception logging, the Exception that you receive will be the FatalException that you made with your message. The original Exception is in ex.InnerException
. You can continue to cycle through InnerException until it's null to get all of the Stack Trace information, etc.
Solution 3:
In short, don't.
I'm sure you could find some way of getting around this with some reflection, but I would strongly caution you against this. It goes against the original design of exceptions in .NET. Exceptions are not just there to help with logging, they provide information about the original cause of an application failure.
Using the first option is generally preferred as it maintains the stack trace of the original exception but allows you to provide additional information by wrapping it in a separate exception. In my own code, whenever I log exceptions, my logging function will recurse through the InnerException property to find every bit of useful information possible about the error.