0

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
  }
lloydom
  • 377
  • 2
  • 11
  • 6
    Are you really prepared to handle an `OutOfMemoryException`? – Jon Feb 06 '13 at 10:41
  • 1
    This is a very general question which can have a lot of oppinionated and debatable answers. In my personal oppinion answer, only trap expected exceptions you want to handle. Like opening a file for example and trapping file access exceptions to allow yourself to re-try a few times before giving up, or file doesn't exist exception because you might want to specificaly send a message about this to the client. Unexpected exceptions should bubble up and be logged by your logger and generate that nice client friendly `oops` page. Then alter as required from there. – Nope Feb 06 '13 at 10:50

6 Answers6

9

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.

Habib
  • 219,104
  • 29
  • 407
  • 436
  • 2
    I don't think the question is about how to *order* the `catch` blocks. – Jon Feb 06 '13 at 10:44
  • 1
    @Jon, may be, but My reply is with respect to this sentence `Why is it adviced most of the time that we should not trap errors like "Exception" but trap errors that we expect as developers.` -- – Habib Feb 06 '13 at 10:45
  • The current form of this answer does *nothing at all* to answer the question you mention. The OP asks "why should/shouldn't I write `catch(Exception)` instead of e.g. `catch(ObjectDisposedException)`", not "how do I order the `catch` blocks if there are more than one". – Jon Feb 06 '13 at 10:48
  • 1
    @Jon: The current form of the question makes it quite unanswerable as it is to general and not constructive in my humble oppinion. There is to many personal preferences and opponions on this topic and all can be right, wrong and very debatable in one way or another, not a good fit for Q&A I think in general. – Nope Feb 06 '13 at 10:55
  • @Jon, I think I didn't get the question, if its about catching specific exception then YES, always catch the specific exception, but if its about whether to use exceptions or have checks in place in code, then I have edited my answer to reflect that. – Habib Feb 06 '13 at 10:56
  • @FrançoisWahl: I don't quite agree. Your long comment-answer at the top is a good attempt to answer the question. *This* answer completely misses the point. – Jon Feb 06 '13 at 10:56
  • @Jon I agree with you, this answer seem to explain a generic exception handling best practice; but regarding the question, answer does not provide any information about the question. – daryal Feb 06 '13 at 11:26
  • 1
    @Jon , i was really trying to understand 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 – lloydom Feb 06 '13 at 11:39
  • @daryal, I have edited the answer, But I think the OP is asking for completey different thing – Habib Feb 06 '13 at 11:41
4

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.

Peter Porfy
  • 8,921
  • 3
  • 31
  • 41
  • peter this makes sense , what i was really getting at with the question is that if some one were to just handle EXCEPTION, then would there be a Performance issue rather than catch particular exception like SQLEXCEPTION? – lloydom Feb 06 '13 at 11:36
  • I don't think that the exception type makes any performance difference. By the way, if you encounter performance issues with exception handling then the problem lies somewhere else. Here are a couple of articles about this topic: http://stackoverflow.com/a/891230/238682 I recommend all of them. – Peter Porfy Feb 06 '13 at 11:48
2

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.

C-va
  • 2,910
  • 4
  • 27
  • 42
1

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.

LukeHennerley
  • 6,344
  • 1
  • 32
  • 50
1

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.

BambooleanLogic
  • 7,530
  • 3
  • 30
  • 56
1

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).

Bojan Komazec
  • 9,216
  • 2
  • 41
  • 51