I am creating a test logger which will include information about any exceptions that are thrown so that they can be displayed properly using a GUI.
Is it safe to use the following construct:
public class TestLogEntry {
public System.Exception Exception { get; private set; }
public TestLogEntry(/*...,*/ System.Exception exception = null) {
//...
Exception = exception;
}
}
Or would the following be better?
public class TestLogEntry {
public string StackTrace { get; private set; }
public System.Type ExceptionType { get; private set; }
public string ExceptionMessage { get; private set; }
public TestLogEntry(/*...,*/ System.Exception exception = null) {
//...
if (exception != null) {
StackTrace = exception.StackTrace;
ExceptionType = exception.GetType();
ExceptionMessage = exception.Message;
}
}
}
Whilst the first approach is more flexible (because it can contain additional custom data), here are my concerns:
- Holding on to exception object for a prolonged period.
- Using a lot of memory if exception objects are preventing large objects from being garbage collected.
- Exception returning wrong values when accessed out of context.
Q1. Are the above concerns valid?
Q2. Do exception objects typically reference a lot of other data?
Your concerns are valid: exception objects might hold onto arbitrary other objects. This is very rare in practice. Actually I have never seen the
Exception.Dataproperty used. But I have seen anExceptionderived class hold onto something big using custom fields:WebExceptionhas aWebResponseproperty!So you see you might be keeping alive even something as expensive as an unmanaged resource.
I’d actually copy out the information and discard the
Exception. Remember to also copy theInnerException.A different concern might be that
Exceptionis a mutable type. You can throw it at any time altering its stack trace. I’d like to capture its state just for that reason.Also important is memory usage. Exception has some fields that are probably never used. You can save them. Also, inlining its fields into your log message object will eliminate the object header and object reference. A small gain but maybe worth taking in case of frequent exceptions.