Like many enterprise organizations, Martin’s workplace decided that they needed to build a collection of .NET assemblies which would be used in every application they built, and would provide important facilities like error handling.

And of course, not only would every application need to use these libraries, every application needed to make use of every component in them, otherwise why have the libraries at all? This meant that every Exception thrown by the application needed to inherit from the BaseException class:

    public class BaseException : System.ApplicationException
    {
        public BaseException(object oSource, int nCode, string sMessage, System.Exception oInnerException, bool bLog) : base(sMessage, oInnerException)
        {
            if (oSource != null)
                base.Source = oSource.ToString();

            Code = nCode;

            if (bLog)
            {
                // trace listeners should already initialized, this
                // is called to be prudent
                Utilities.InitTraceListeners();

                // log it
                 try
            {
                Foo.DAL.Utility.ExceptionHandling.BaseException.Track("", message);
            }
            catch(Exception ex)
            {
                //Handle db logging error
                SendEmail(ConfigurationManager.AppSettings["AdminEmail"], "",
                    ConfigurationManager.AppSettings["ErrorAlertEmail"],
                    "Database Error Logging Error", ex.Message + Environment.NewLine + message, "");
            }
            }
        }

    }

As Martin explains:

I found this gem at the heart of our grand, all-encompassing, be-all, end-all, work-permanently-in-progress, Godot of a One System To Rule Them All, which is supposed to be a set of assemblies that can be included in every application our department produces. Someone had the avant-garde idea of putting database-logging code, config-file-reading code and another try/catch inside the constructor for a custom exception. Every exception in every application is supposed to inherit from this.

Why handle an exception when you can build an exception object that handles itself?

Of course, reading from the ConfigurationManager may throw an exception for a number of reasons, which is never caught, meaning that throwing an exception can, in some cases, throw an exception.

[Advertisement] BuildMaster allows you to create a self-service release management platform that allows different teams to manage their applications. Explore how!