My problem with DefaultTraceListener
(which is the only trace listener, if not overridden in app.config) is that, if AssertUiEnabled
is false
(i.e. in ASP.NET) it writes a message as OutputDebugString
on failed assertions (calls to Trace.Assert(false)
), but continues the execution.
So I'm using the following sub-class of TraceListener
, which instead throws an exception. I activate it using
TraceListenerWhichThrowsExceptionOnFail.InsertAsFirstTraceListener(Trace.Listeners);
in Application_Init
.
Now, in the Application_Error
event I can log the exception (as any exception) with the full stack trace, including the call of Trace.Assert(false)
.
public class TraceListenerWhichThrowsExceptionOnFail : TraceListener
{
public static void InsertAsFirstTraceListener(TraceListenerCollection traceListeners)
{
traceListeners.Insert(0, new TraceListenerWhichThrowsExceptionOnFail());
}
public override void Fail(string message, string detailMessage)
{
message = string.IsNullOrEmpty(detailMessage) ? message : message + ", Detail message: " + detailMessage;
throw new ApplicationException("Trace assertion failed" +
(string.IsNullOrEmpty(message) ? "" : ": " + message) + ".");
}
public override void Write(string message)
{
// NOP
}
public override void WriteLine(string message)
{
// NOP
}
}
Now my question: Does anyone see a problem with this approach?
I'd say exception in Trace.Assert is bad idea (not looking at your code).
Trace.XXXX methods generally used to trace stuff. It would be very surprising to future readers (including you) to learn that
Trace.Assert
actually throws exception.It is even more surprising to see Trace.Assert (or even Fail) throwing exception. Purpose of Assert is to help identify issues in advance, not to kill application.
I'd recommend to come up with your custom method that clearly shows its behavior in the name instead of coming up with unexpected behavior of existing methods.