Subclassing Exception to log some contextual information

Today I arrived at work to find some truly wonderful emails in my inbox, containing the informative error:

String or binary data would be truncated.

So somewhere in a public method, one of the members of a structure in scope was too big for the database field we tried to save it to, and something somewhere was unable to save. Easy to fix if I know what method and what field it was, but I know nothing of the sort. Now what?

The error handlers in this application simply email the error message to everyone in the team. I needed a quick and dirty way to extend them such that they logged whatever relevant contextual information was available in the scope of the method that broke.

I decided to subclass Exception, adding a collection of objects to my custom exception, then have a LogError method that returns a string, on my derived class, so that I can simply call it in the methods that handle exceptions and send emails. It worked out quite nicely.

Unlike last time, I can share this code, because this time it is all downloaded from StackOverflow. I used the code from…

What this code does is, it logs every error message from the topmost Exception and every inner Exception, and then lists all of the instances added to the contextInfo parameter by class name, with the name and value of each public property of those instances on a new line. This was more than enough to tell me exactly what the issue was.

Here is the code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SampleWcfService
{
    internal static class ExceptionExtensions
    {
        public static IEnumerable<TSource> FromHierarchy<TSource>(this TSource source,
            Func<TSource, TSource> nextItem, Func<TSource, bool> canContinue)
        {
            for (var current = source; canContinue(current); current = nextItem(current))
            {
                yield return current;
            }
        }

        public static IEnumerable<TSource> FromHierarchy<TSource>(this TSource source,
            Func<TSource, TSource> nextItem) where TSource : class
        {
            return FromHierarchy(source, nextItem, s => s != null);
        }

        public static string GetaAllMessages(this Exception exception)
        {
            var messages = exception.FromHierarchy(ex => ex.InnerException)
                .Select(ex => ex.Message);
            return String.Join(Environment.NewLine, messages);
        }
    }

    public class SampleServiceException : Exception
    {
        private List<object> contextInfo = new List<object>();

        public SampleServiceException(string message, Exception innerException, List<object> contextInfo)
            : base(message, innerException)
        {
            this.contextInfo = contextInfo;
        }

        public string LogError()
        {
            StringBuilder builder = new StringBuilder();

            builder.AppendLine("Exception: " + this.GetaAllMessages());
            builder.AppendLine();

            if (contextInfo.Count > 0)
            {
                foreach (var obj in contextInfo)
                {
                    builder.AppendLine(obj.GetType().Name + ":");

                    foreach (var prop in obj.GetType().GetProperties())
                    {
                        builder.AppendLine(prop.Name + " = " + prop.GetValue(obj, null));
                    }
                    builder.AppendLine();
                }
            }

            return builder.ToString();
        }
    }
}

And here is an example of its usage. For brevity, I have omitted error checking and null checking. In practice it may be better to, for example, check that everything you pass to the context info collection is valid, and if you have collections whose properties you need to see, iterate them and pass the members you need…

        public Response ExampleMethod(Request request)
        {
            Response response = new Response();

            try
            {
                try
                {
                    // Do something here that populates response...
                }
                catch (Exception ex)
                {
                    List<object> contextInfo = new List<object>();

                    contextInfo.Add(request);
                    contextInfo.Add(response);

                    throw new SampleServiceException("Unexpected error in ExampleMethod.", ex, contextInfo);
                }
            }
            catch (SampleServiceException sex)
            {
                var errorBody = sex.LogError();

                // Code to notify here, using email or whatever...
            }

            return response;
        }
Advertisements

About Jerome

I am a senior C# developer in Johannesburg, South Africa. I am also a recovering addict, who spent nearly eight years using methamphetamine. I write on my recovery blog about my lessons learned and sometimes give advice to others who have made similar mistakes, often from my viewpoint as an atheist, and I also write some C# programming articles on my programming blog.
This entry was posted in Programming and tagged , . Bookmark the permalink.

1 Response to Subclassing Exception to log some contextual information

  1. Wesley Maskell says:

    Howdy

    SEO Link building is a process that requires a lot of time fo wordpress.com
    If you aren’t using SEO software then you will know the amount of work load involved in creating accounts, confirming emails and submitting your contents to thousands of websites in proper time and completely automated.

    With THIS SOFTWARE the link submission process will be the easiest task and completely automated, you will be able to build unlimited number of links and increase traffic to your websites which will lead to a higher number of customers and much more sales for you.
    With the best user interface ever, you just need to have simple software knowledge and you will easily be able to make your own SEO link building campaigns.

    The best SEO software you will ever own, and we can confidently say that there is no other software on the market that can compete with such intelligent and fully automatic features.
    The friendly user interface, smart tools and the simplicity of the tasks are making THIS SOFTWARE the best tool on the market.

    IF YOU’RE INTERESTED, CONTACT ME ==> seosubmitter@mail.com

    Regards,
    Wesley

    Like

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 )

Google+ photo

You are commenting using your Google+ 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 )

Connecting to %s