lloydom
lloydom

Reputation: 387

C# Error handling catch blocks

Why is it adviced most of the time that we should not trap errors like "Exception" but trap errors that we expect as developers. Is there a performance hit in trapping generic errors or is it recommended from a best practice point of view?

  try
  {
        // Do something
  }
  catch(Exception e)
  {
        //Log error
  }

Upvotes: 0

Views: 827

Answers (6)

Habib
Habib

Reputation: 223257

The best practice is to catch specific exception first and then move on to more generic ones.

Exception Handling (C# Programming Guide)

Multiple catch blocks with different exception filters can be chained together. The catch blocks are evaluated from top to bottom in your code, but only one catch block is executed for each exception that is thrown. The first catch block that specifies the exact type or a base class of the thrown exception is executed. If no catch block specifies a matching exception filter, a catch block that does not have a filter is selected, if one is present in the statement. It is important to position catch blocks with the most specific (that is, the most derived) exception types first.

For your question:

Why is it adviced most of the time that we should not trap errors like "Exception" but trap errors that we expect as developers.

An example would be to catch NullReferenceException. Its never a better practice to catch NullReferenceException, instead one should always check for object being null before using its instance members. For example in case of string.

string str = null;
try
{
   Console.WriteLine(str.Length)
}
catch(NullReferenceException ne)
{
    //exception handling. 
}

instead a check should be in place for checking against null.

if(str != null)
   Console.WriteLine(str.Length);

EDIT:

I think I got the question wrong, If you are asking which exception should be caught and which shouldn't then IMO, those exceptions which can be dealt with should be caught and rest should be left in the library so they can bubble up to upper layer where appropriate handling would be done. An example would be Violation of Primary key constraint. If the application is taking input(including primary key) from the user and that date is being inserted into the database, then that exception can be caught and a message can be shown to user "Record already exists" and then let the user enter some different value.

But if the exception is related to the foreign key constraint (e.g. Some value from the dropdown list is considered invalid foreign key) then that exception should bubble up and a generic exception handler should log it in appropriate place.

For example in ASP.Net applications, these exception can be logged in Application_Error event and a general error page can be shown to the user.

EDIT 2: For the OP's comment:

if at a low level if there would be a performance degeradation in catching a generic error inspite of knowing if the error is sqlexception

Even if there is going to be any performance difference it should be negligible. But Catch the specific exception, if you know that the exception is going to be SqlException then catch that.

Upvotes: 9

C-va
C-va

Reputation: 2910

Check Eric Lippert's blog (Vexing exceptions) about best way to handle exceptions.

• Don’t catch fatal exceptions; nothing you can do about them anyway, and trying to generally makes it worse.

• Fix your code so that it never triggers a boneheaded exception – an "index out of range" exception should never happen in production code.

• Avoid vexing exceptions whenever possible by calling the “Try” versions of those vexing methods that throw in non-exceptional circumstances. If you cannot avoid calling a vexing method, catch its vexing exceptions.

• Always handle exceptions that indicate unexpected exogenous conditions; generally it is not worthwhile or practical to anticipate every possible failure. Just try the operation and be prepared to handle the exception.

Upvotes: 2

Bojan Komazec
Bojan Komazec

Reputation: 9526

Catch those exceptions which you intend to handle. You will usually want to handle particular exception in such context (method) where you have enough information for dealing with error reported (e.g. access to objects used for clean-up).

If code within try block throws different types of exceptions, you might want to handle some exceptions within the same method and re-throw others in order to handle them in the caller method (as in that context you have resources for handling those exceptions).

Upvotes: 1

Peter Porfy
Peter Porfy

Reputation: 9030

You should only catch exceptions what you can handle. Exception is too generic so most of the time you cannot say you can handle that. It is a little funny but you should only catch exception that you except :)

There are situation when you need to catch Exception but rare and you should avoid it most of the time. Usually it indicates some design problem.

Upvotes: 4

BambooleanLogic
BambooleanLogic

Reputation: 8161

It's a best practice thing. The idea is that you should quickly handle the known exceptions explicitly while having more general ones higher up in the program as unexpected exceptions are likely caused by some more major/fundamental error.

Upvotes: 1

LukeHennerley
LukeHennerley

Reputation: 6434

Using exception handling more often than required is infact a lazy way of programming more than anything. Say you have a DataTable and you want to access the first row.

public DataRow AccessFirstRow(DataTable dt)
{
  try
  {
    return dt.Rows[0];
  }
  catch (Exception e)
  {
    //There isn't a first row or dt is null
  }
}

Instead of

public DataRow AccessFirstRow(DataTable dt)
{
  if(dt != null)
   if(dt.Rows.Count > 0)
     return dt.Rows[0];
  //If we can't access dt, then don't
  return null;
}

My rule of thumb is:

Exceptions should only be used in EXCEPTION-al circumstances.

If you do decide to handle them though, as mentioned handle specific exceptions you know you might encounter instead of generic exceptions.

Upvotes: 1

Related Questions