locked
Best way to display an Exception? RRS feed

  • Question

  • Hi,

    Because log4net doesn't pick up every details from an exception, I want to write an extension that does the job right. Now I've always thought that exception.ToString() was nice - it gives a great stack trace to look at. But that is just not enough. There is the Data dictionary and LoaderExceptions etc. 

    But I need some opinions/examples on how an exception should look - for example written to a log file. I need all data in the exception(s) displayed. Personally, I would prefer a stack-view that is at least as nice to look at as exception.ToString().

    Perhaps anyone have some examples code that takes an exception and spits out a string that is nice and human readable? 

    -- 
    Werner


    Tuesday, March 5, 2013 9:47 PM

Answers

  • Hi Werner,

      Welcome to MSDN Forum Support.

      I feel that you want to know how to create a custom exception,I suggest you that ou can read this article named How to create a custom c# exception?.

      Sincerely,

      Jason Wang


    Jason Wang [MSFT]
    MSDN Community Support | Feedback to us

    • Marked as answer by Jason Dot Wang Wednesday, March 13, 2013 9:10 AM
    Thursday, March 7, 2013 6:51 AM
  • You can use a while loop to iterate over InnerException until it's null, should be really easy to do.


    Regards,

    Eyal Shilony

    • Proposed as answer by Jason Dot Wang Wednesday, March 13, 2013 9:10 AM
    • Marked as answer by Jason Dot Wang Wednesday, March 13, 2013 9:10 AM
    Tuesday, March 12, 2013 3:06 PM

All replies

  • What I do when writing exceptions to a log file is something like this (in pseudo code):

    Write the exception
    if there is an inner exception, write the inner exception
    Write any other desired details.


    - Eric www.my-msi.net/Admin

    Tuesday, March 5, 2013 9:57 PM
  • Hi Werner,

      Welcome to MSDN Forum Support.

      I feel that you want to know how to create a custom exception,I suggest you that ou can read this article named How to create a custom c# exception?.

      Sincerely,

      Jason Wang


    Jason Wang [MSFT]
    MSDN Community Support | Feedback to us

    • Marked as answer by Jason Dot Wang Wednesday, March 13, 2013 9:10 AM
    Thursday, March 7, 2013 6:51 AM
  • Hi Jason,

    No not at all. Basically I am after the best (perhaps someone already did it) way to serialize any exception to string.

    --
    Werner


    Thursday, March 7, 2013 7:38 AM
  • Hi Jason,

    No not at all. Basically I am after the best (perhaps someone already did it) way to serialize any exception to string.


    Yes, u have to make another class to inherit from Exception and override ToString() method. And then show it out in default;)

    If you think one reply solves your problem, please mark it as An Answer, if you think someone's reply helps you, please mark it as a Proposed Answer

    Help by clicking:
    Click here to donate your rice to the poor
    Click to Donate
    Click to feed Dogs & Cats

    Thursday, March 7, 2013 7:42 AM
  • What I do when writing exceptions to a log file is something like this (in pseudo code):

    Write the exception
    if there is an inner exception, write the inner exception
    Write any other desired details.


    - Eric www.my-msi.net/Admin

    Yes but it is the "desired details" I'm after. I want this to be the best possible serialization of any exception.

    Thursday, March 7, 2013 8:27 AM
  • Why?!

    If you think one reply solves your problem, please mark it as An Answer, if you think someone's reply helps you, please mark it as a Proposed Answer

    Help by clicking:
    Click here to donate your rice to the poor
    Click to Donate
    Click to feed Dogs & Cats

    Thursday, March 7, 2013 8:28 AM
  • Why?!

    If you think one reply solves your problem, please mark it as An Answer, if you think someone's reply helps you, please mark it as a Proposed Answer

    Help by clicking:
    Click here to donate your rice to the poor
    Click to Donate
    Click to feed Dogs & Cats


    Because Exception.ToString() itsn't good enough.
    Thursday, March 7, 2013 11:53 AM
  • Hi Jason,

    No not at all. Basically I am after the best (perhaps someone already did it) way to serialize any exception to string.


    Yes, u have to make another class to inherit from Exception and override ToString() method. And then show it out in default;)

    If you think one reply solves your problem, please mark it as An Answer, if you think someone's reply helps you, please mark it as a Proposed Answer

    Help by clicking:
    Click here to donate your rice to the poor
    Click to Donate
    Click to feed Dogs & Cats

    Yes, but once Again, it is the code in "ToString()" that I'm after.

    Thursday, March 7, 2013 11:55 AM
  • I am not 100% sure what are you intentions. Have you consider try-catch statement as a solution to your problem? You can call Message property of exception instance to display the entire exception.

    Microsoft Student Parnter Microsoft Technology Associate

    Thursday, March 7, 2013 7:04 PM
  • Good question. Can you explain more about your idea of extension method? Do you want a new extension method for the exception object?

    I recently added the following for handling SqlException although I don't think it's enough or comprehensive enough:

    private void HandleSqlException(SqlException ex, SqlCommand sqlCommand, out string returnMessage, out int statusCode)
          {
             if (null != ex.InnerException)
                returnMessage = ex.InnerException.ToString();
             else
                returnMessage = ex.Message;
    
             statusCode = ex.Number;
             StringBuilder errorMessages = new StringBuilder();
             for (int i = 0; i < ex.Errors.Count; i++)
             {
                String procedure = ex.Errors[i].Procedure;
                if (String.IsNullOrEmpty(procedure))
                   procedure = sqlCommand.CommandText;
    
                errorMessages.Append("Index #" + i + "\n" +
                    "Message: " + ex.Errors[i].Message + "\n" +
                    "LineNumber: " + ex.Errors[i].LineNumber + "\n" +
                    "Source: " + ex.Errors[i].Source + "\n" +
                    "Procedure: " + procedure + "\n");
             }
             Logging.Log(1, errorMessages.ToString());
          }


    For every expert, there is an equal and opposite expert. - Becker's Law


    My blog

    Thursday, March 7, 2013 8:10 PM
  • Improper Exception Handling is the #2 most common bug related issue in IT.

    There is a proper way to handle exceptions as well as to inform the user what's going on.

    Rule #1 "The user should be in control of the application at all times.

    • This requires the application to always maintain state.  For example go to Amazon add something to your cart, come back 5 days from now and it's still there! 
    • If a user makes a mistake they should always be able to undo it.
    • Users should be able to cancel out of a transaction at any time.

    Rule #2 "All code should be bullet proof"

    • No unhandled exception (as Eyal said) should ever surface to the user. 
    • This means there are at least two layers of protection  1) The System layer e.g. System.Exception usually done at a more Global level and 2) Specific Exceptions monitored everywhere!  For Example : An IO operation only throws certain types of errors.  Those certain types should be condisdered, monitored and handled correctly.

    Rule #3 "All exceptions must produce enough data for the developer to diagnose" 

    • Should almost always have a copy of the Stack trace where needed.
    • Should consider flight recording.
    • Sometimes it is good to start a memory dump.
    • Any other aritifact that will help developer dial-into the root cause ASAP.

    Rule #4 "Messages displayed to the user must be"

    • Meaningful...  "Object Reference not set to instance of object" has no meaning to an End User
    • This requires the developer to think about translating the actual exception to something that is pertinent to the work being done that gives the user a clue.
    • All error messages should have a Unique ID. This is the most simple thing to implement with huge payoffs. If all messages are unique, the developer can automatically zero in on the code!

    So in general there are two layers to consider, the User and the Developer, exception handling must meet both audiences so that the ALM of the product is maintainable. Without doing this type of thing, the work for both the User and the Developer becomes very difficult at a time when more complexity is not needed. 


    JP Cowboy Coders Unite!


    Thursday, March 7, 2013 9:17 PM
  • Rule #2 "All code should be bullet proof"
    • No unhandled exception (as Eyal said) should ever surface to the user. 

    I've deleted my post because I thought it's irrelevant so you might be able to elaborate more on that because you went with a more thorough explanation.

    I think that the OP knows how to handle the exception so he's asking for a way to log everything from the stack trace to the actual data at the time of the exception.


    Regards,

    Eyal Shilony

    Thursday, March 7, 2013 9:34 PM
  • Intellitrace aside, the best way in my opinion is to create a database that is only for errors.  When any exception is hit, that DB table logs an entry with the proper fallout.  By doing this, the particular server, keeps track of things which are important to measure.  For example we have to be able to answer this question "What part of our application is having the most trouble" 

    If we take this one level higher at a corporate level, the same question is asked "Of all of our applications, which ones need the most help?"  We can only do this if we have metrics that tell us!

    MSFT agrees with these concepts and has implemented this type of function in SCOM (Support Center Operations Manager).  In fact they went one step further by allowing SCOM to crreate bug reports that get assigned to developers via TFS!  SCOM monitors an entire enterprise for exceptions and brings it all back to the developer.  Pretty cool in my opinion.


    JP Cowboy Coders Unite!

    • Proposed as answer by Naomi N Thursday, March 7, 2013 11:46 PM
    • Unproposed as answer by Werner Clausen Monday, March 11, 2013 2:01 PM
    Thursday, March 7, 2013 10:47 PM
  • One other note, what is intellitrace?  It's a built-in flight recorder that requires no tooling in code to track program flow or to collect preconfigured data.  Similar to setting up a lab environment using MTM and submitting a bug that already has all the information the developer needs.  Lab Manager has the ability to write custom data collection agents too...  All the bases are covered and it requires nobody spending hours to get the data.

    JP Cowboy Coders Unite!

    Thursday, March 7, 2013 10:50 PM
  • I'm going to use "NullReferenceException", but remember there are many different kinds, but here is some code you could use:

    private void Temp()
            {
                string msg = null;
                try
                {
                    if (msg == "Hello World!")
                        msg = msg.ToLower();
                }
                catch (NullReferenceException error)
                {
                    this.writeExceptionFile(error.Message.ToString());
                }
            }
    
    private async void writeExceptionFile(string contents)
            {
                StorageFile file = await Windows.Storage.KnownFolders.DocumentsLibrary.CreateFileAsync("ExceptionFile", CreationCollisionOption.GenerateUniqueName);
                Stream stream = await file.OpenStreamForWriteAsync();
            }

    I wrote a temp method just for example and in the catch (since you can't use await in catch statements) I have my own method that writes the contents of the error to the "Documents Folder".

    Thursday, March 7, 2013 11:42 PM
  • Thanks to you all. I'm glad to see that I'm not the only one thinking about these issues. And while I find Mr. Javaman II's posts both true and on topic, they aren't the answers I was looking for. The others that have produced some code are examples of what I'm after.

    My specific issue is how to best serialize an exception (e.g. to file), and not how to handle it. Think of an unhandled exception serializer...

    It seems to me, that if there are 100 developers catching unhandled exceptions, 50 of them are just passing the exception to their log method (e.g. log4net "log.Error(ex)") utilizing "ToString" and such - in other words, missing out on a lot of information. And the remaining 50 developers have 50 different ways of serializing an exception.   

    Monday, March 11, 2013 2:13 PM
  • I believe that Log4Net is good.  Will this post help on the serialization aspect?

    http://weblogs.asp.net/stevewellens/archive/2009/07/02/serializing-and-deserializing-objects-to-and-from-xml.aspx


    JP Cowboy Coders Unite!

    Monday, March 11, 2013 2:42 PM
  • I believe that Log4Net is good.  Will this post help on the serialization aspect?

    http://weblogs.asp.net/stevewellens/archive/2009/07/02/serializing-and-deserializing-objects-to-and-from-xml.aspx


    JP Cowboy Coders Unite!

    Personally I think log4net (out of the box) is really bad at logging exception objects. All it does is calling the exception "ToString()". You get no properties from the exceptions other than the common from System.Exception. It doesn't even print out the base dictionary of the exception. Not to mention LoaderExceptions which are completely lost also.

    Your link is about XML serialization - and Exceptions can't be serialized using the XmlSerializer.

    My current thought now, is to loop the exception and inspect it's properties using reflection. This should be accepted as we are in an exceptional situation :). Then recursive call that method for every property that is an exception also (e.g. inner exception). Each property would then either be a collection (e.g. the Data dictionary or SqlException.Errors) - or something where the value can be stored as "ToString()". Also remember to inspect for LoaderExceptions. Perhaps make something special out of formatting also (e.g stack traces).

    Then (as we use log4net) I will need to create my own implementation of the log4net PatternLayoutConverter where I can write the outcome of the above logic...

    --
    Werner
     

     

    Tuesday, March 12, 2013 2:20 PM
  • Ok but...

    The Excpetion.Message is a string and the Exception.Stack is a string too.  So, can't Log4Net serialize strings?


    JP Cowboy Coders Unite!

    Tuesday, March 12, 2013 2:28 PM
  • Ok but...

    The Excpetion.Message is a string and the Exception.Stack is a string too.  So, can't Log4Net serialize strings?


    JP Cowboy Coders Unite!

    Out of the box, log4net just call "ToString()" of the exception. By default this would print out both the message and the stacktrace. But there might be other (important) information that isn't printed using "ToString()".

    Tuesday, March 12, 2013 2:32 PM
  • True, many times I have to dig into Innerexceptions 2 or more layers deep.

    So it this isn't going to work for you then it's back to a database design right?

    I'm wondering how MSFT does it with TFS?  When you run a Test Case and file a bug report it collects everything you need automatically.  Maybe you can interface with TFS to send residual data. As well as create a new bug report.


    JP Cowboy Coders Unite!


    Tuesday, March 12, 2013 3:02 PM
  • You can use a while loop to iterate over InnerException until it's null, should be really easy to do.


    Regards,

    Eyal Shilony

    • Proposed as answer by Jason Dot Wang Wednesday, March 13, 2013 9:10 AM
    • Marked as answer by Jason Dot Wang Wednesday, March 13, 2013 9:10 AM
    Tuesday, March 12, 2013 3:06 PM
  • There are different ways to save the application errors, some developers like to save logs in database while some in text file. Text file responds much quicker then database. I am discussing here to write error log in text file. This will log all errors with date and time in text file.

    For more with example : http://cybarlab.blogspot.com/2013/03/write-error-log-into-file-in-c-sharp.html

    Tuesday, March 26, 2013 5:43 AM