clr20r3: The World’s least helpful runtime error

You’ve got to wonder what people were thinking when they designed .NET’s behaviour when encountering an unhandled exception.  Sensibly, it writes the event log.  Stupidly, it writes garbage you can’t read.  Let’s just appreciate it in all its glory.

clr20r3

Good luck figuring out what the problem was.  (Actually, the server was down, but that’s hardly the point…)  It’s pretty easy to say “Well, you should just catch all exceptions in Main.” but it misses the point.  Any thread failing can cause this to happen, and if you’re using third party libraries they’re not necessarily under your control.  So disciplined coding isn’t going to help you on this one.  Trawling the internet, on the other hand, will.  At least, if you look for long enough.  What you need to do is to put a handler on the domain’s unhandled exception event.  Here’s the code:

private static void LogUnhandledExceptions(string source, int fatalEventId)
{
    AppDomain.CurrentDomain.UnhandledException += delegate(object sender, UnhandledExceptionEventArgs e)
    {
        if (!(e.ExceptionObject is System.Threading.ThreadAbortException))
        {
            Exception exception = e.ExceptionObject as Exception;
string message = exception == null ? e.ExceptionObject == null ? "Missing exception" : e.ToString() : string.Format("Fatal Error {0}: {1}rn{2}", exception.GetType().FullName, exception.Message, exception.StackTrace); try { System.Diagnostics.EventLog.WriteEntry(source, message, System.Diagnostics.EventLogEntryType.Error, fatalEventId); } catch { try { System.Windows.Forms.MessageBox.Show(message, "Fatal Error",
MessageBoxButtons.OK, MessageBoxIcon.Stop); } catch { if (Console.Error != null) { Console.Error.WriteLine(message); } Console.WriteLine(message); } } } }; }

I kid you not, cut and paste this routine into every system you ever write, and make it the absolute first thing that gets called.  Some of this code is probably redundant (is Console.Error ever null, for instance?).  It won’t solve your problem, but at least you’ll be able to see the error message.  Note that this code is not configurable in any way, since it needs to run before configuration.  So log4net et al can’t be used.  Incidentally, the clr20r3 error will still appear, so code discipline is still worth practicing.

Now, I can’t count the number of times I’ve thought that Microsoft had made a bone-headed design decision which later turned out to be quite smart but really, why doesn’t the .NET runtime log a readable error by default?

Published by

Julian Birch

Full time dad, does a bit of coding on the side.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s