Click here to Skip to main content
13,145,068 members (57,646 online)
Click here to Skip to main content
Add your own
alternative version

Stats

8.8K views
121 downloads
13 bookmarked
Posted 30 Mar 2017

A Quick and Dirty Extension Method to Get the Full Exception Details, Including Inner Exceptions

, 1 Apr 2017
Rate this:
Please Sign up or sign in to vote.
This tip presents an easy way of verbosely converting an exception and its inner exceptions to a string in order to get access to all details.

Introduction

While exception messages are often clear enough, many times the sole error is "An error occurred while updating the entries. See the inner exception for details." - Everyone who's worked with the entity framework probably stumbled upon this one before - See this post on StackOverflow.com, for example.

Background

This code snippet is intended as an easy way of improving the logged details if the logging framework doesn't support a verbose way of logging inner exceptions. Since it is basically boilerplate code which can be used in any .NET project, I decided to put it up here, for further reference to me (and others) - I can't see why everyone should be writing the same piece of code over and over again. Feel free to adapt it to your individual needs.

Mind you, if you have any other way to get the full exception details, you should probably use that way.

Using the Code

The code itself basically consists of a single static class holding an extension method ToFullBlownString. If you're not familiar with extensions methods, read it up here.

public static class ExceptionExtension
        {
            public static string ToFullBlownString(this System.Exception e, int level = int.MaxValue)
            {
                var sb = new StringBuilder();
                var exception = e;
                var counter = 1;
                while (exception != null && counter <= level)
                { 
                  sb.AppendLine($"{counter}-> Level: {counter}");
                  sb.AppendLine($"{counter}-> Message: {exception.Message}");
                  sb.AppendLine($"{counter}-> Source: {exception.Source}");
                  sb.AppendLine($"{counter}-> Target Site: {exception.TargetSite}");
                  sb.AppendLine($"{counter}-> Stack Trace: {exception.StackTrace}");

                  exception = exception.InnerException;
                  counter++;
                }

            return sb.ToString();
            }
        }

The exception extension basically does the following:

As long as the exception is not null, and counter is below level:

-- print exception level (level is increased for every inner exception)
-- print exception message
-- print exception source
-- print exception target site
-- print exception stack trace

-- - > exception is set to exception.inner exception
-- - > counter is increased by one
-- - > evaluate start condition As long as the exception is not null, and counter is below level again and start over.

Example Output

I've written a little test program which generates an exception containing an inner exception. I called ToFullBlownString twice, once without specifying the level parameter and once with the level parameter set to "1":

The test program (which is also included in the source code download) looks like this:

static void Main(string[] args)
        {
            try
            {
                var exception = new Exception("This is an exception. 
                                Please see inner exception for details", GetInnerException());
                throw exception;
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToFullBlownString());
                Console.WriteLine("\n\n\nand now with level = 1:");
                Console.WriteLine(e.ToFullBlownString(1));
            }

            Console.WriteLine("Press any key to exit");
            Console.ReadKey();
        }

        private static Exception GetInnerException()
        {
            try
            {
                throw new Exception("This is the inner exception. 
                               If this was production code, 
                               you'de be presented with details here.");
            }
            catch (Exception e)
            {
                return e;
            }
        }

Further Considerations

Please bear in mind that exception objects sometimes do contain information not meant for everyone to see, for example connection strings and the like. Be careful of what you put into your logfile or display to the end user.

History

  • March 30th, 2017: Initial release
  • April 1st, 2017: Replaced screenshot, added chapter "Further considerations"

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Marco Bertschi (SFC)
Software Developer (Junior)
Switzerland Switzerland
Software Developer (Swiss Federal VET Diploma), experienced with Qt C++, Arduino Boards, multiple communication technologies (the usual Webservices, TCP/IP bunch as well as serial port communication), and C# including WPF, Entity Framework and COM libraries built using the .Net Framework.
Music enthusiast, runner, part-time psychologist for friends, awesome guy and Air Force Sergeant First Class.

You may also be interested in...

Pro
Pro

Comments and Discussions

 
SuggestionEF System.Data.Entity.Validation.DbEntityValidationException Pin
martinrj303-Apr-17 15:49
membermartinrj303-Apr-17 15:49 
GeneralRe: EF System.Data.Entity.Validation.DbEntityValidationException Pin
Marco Bertschi (SFC)3-Apr-17 22:26
protectorMarco Bertschi (SFC)3-Apr-17 22:26 
GeneralNot very good Pin
SteveTheThread1-Apr-17 12:37
memberSteveTheThread1-Apr-17 12:37 
GeneralRe: Not very good Pin
Marco Bertschi (SFC)2-Apr-17 20:45
protectorMarco Bertschi (SFC)2-Apr-17 20:45 
GeneralMy vote of 5 Pin
BillWoodruff31-Mar-17 17:19
mvpBillWoodruff31-Mar-17 17:19 
GeneralRe: My vote of 5 Pin
Marco Bertschi (SFC)1-Apr-17 6:19
protectorMarco Bertschi (SFC)1-Apr-17 6:19 
GeneralMy vote of 5 Pin
Member 787034531-Mar-17 1:30
professionalMember 787034531-Mar-17 1:30 
GeneralRe: My vote of 5 Pin
Marco Bertschi (SFC)31-Mar-17 2:44
protectorMarco Bertschi (SFC)31-Mar-17 2:44 
Questionsuggest you post this as a 'Tip' rather than article Pin
BillWoodruff31-Mar-17 0:07
mvpBillWoodruff31-Mar-17 0:07 
AnswerRe: suggest you post this as a 'Tip' rather than article Pin
Marco Bertschi (SFC)31-Mar-17 2:43
protectorMarco Bertschi (SFC)31-Mar-17 2:43 
GeneralMy vote of 5 Pin
0x01AA30-Mar-17 6:50
professional0x01AA30-Mar-17 6:50 
GeneralRe: My vote of 5 Pin
Marco Bertschi (SFC)30-Mar-17 11:37
protectorMarco Bertschi (SFC)30-Mar-17 11:37 
GeneralRe: My vote of 5 Pin
0x01AA1-Apr-17 2:36
professional0x01AA1-Apr-17 2:36 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Terms of Use | Mobile
Web04 | 2.8.170915.1 | Last Updated 1 Apr 2017
Article Copyright 2017 by Marco Bertschi (SFC)
Everything else Copyright © CodeProject, 1999-2017
Layout: fixed | fluid