Question

I am fairly new to programming and I want to know what is the proper way to structure your error handling. I have searched the internet but I have failed to find something solid about the structure of ALL your try/catch/finally statements, and how they interact with each other.

I want to present my idea of how I think I should structure my error handling in code and I would like to invite everyone check if this is correct. A big bonus would be to back it up with some other research, a common practice of some sort.

So my way of doing this would be to put try statements pretty much everywhere! (I hope I haven't raged everyone by saying this). PS - I also understand about catching different types of exceptions, I am only catching of type 'Exception' just for explanation purposes.

So for example:

  1. I start on Main in a normal console application and then I create an instance of A.

  2. I then call a member function on it called AMethod1 (a.AMethod1).

  3. A.AMethod1 creates an instance of class B and then calls BMethod1 (b.BMethod1).

This is how I would go about error handling it:

    public class Program
    {
       static void Main (string[] args)
       {
          //I do not place simple code like below inside the try statement, 
          //because it is unnecessary and will slow the process down.
          //Is this correct?

          const int importantNumber = 45;
          string name;
          IRepositoryFactory repoFactory;
          A a; 

          //And then I put code in 'try' where I feel it may go wrong.
          try
          {
             a = new A();
             a.AMethod1();

             //Some other code    
          }
          catch (Exception ex)
          {
             HandleError(ex);
          }
       }
    } 
    // End of scope of Program! The functions below belong to their relative 
    // classes.

    public void AMethod1()
    {
       try
       { 
          B b = new B();
          b.BMethod1(); 
       }
       catch (Exception ex)
       { 
          //Preserving the original exception and giving more detailed feedback.
          //Is this correct?
          //Alternative - you still could do a normal 'throw' like in BMethod1.
          throw new Exception("Something failed", ex); 
       }
    }

    public void BMethod1()
    {
       try
       { 
          //some code 
       }
       catch (Exception ex)
       { 
          throw; //So I don't lose stack trace - Is this correct?
       }
    }

In summary:

  1. I put all code in try statements (except declarations like shown in above code)
  2. On the client level (at the start of the call stack) I catch the error and handle it.
  3. Going down the call stack, I just throw the Exception so I don't break the stack information.

I would really appreciate some resources that explains how programmers are meant to structure their error handling. Please don't forget to read the comments within the code please.

Was it helpful?

Solution

Here are some good rules of thumb:

  1. If you are going to log the error at the level in question, use exception handling
  2. If there is some way to solve the exception, use exception handling
  3. Otherwise, don't add any exception handling at that level

The exception to the rules above is the UI should ALWAYS (okay, maybe not always, but I can't think of an exception to this rule right off hand) have exception handling.

In general, if you are throwing the same error, as you have in your code, it is a sign you should not handle the exception. End of story.

NOTE: When I say "at that level", I mean in the individual class or method. Unless the exception handling is adding value, don't include it. It always adds value at the user interface level, as a user does not have to see your dirty laundry, a message saying "oops, laundry day" is enough.

OTHER TIPS

In my personal experience most of the exceptions are related to null object reference. I tend to follow null object pattern to avoid lots of check for null values. And also while doing a value conversion I always use tryparse so that i dont stand a chance of null issues. all in all this subject could be discussed from many perspective. if you could be a bit more specific it will be easy to answer.

stackoverflow really isn't an opinion site. It's geared heavily towards specific answers to specific questions.

But you should know that try...catch does have some overhead associated with it. Putting it "everywhere" will hurt the performance of your code.

Just use it to wrap code that is subject to unexpected errors, such as writing to disk, for example.

Also note that the "correct" way depends on what you are doing with those errors. Are you logging them, reporting them to the user, propagating them to the caller? It just depends.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top