2

Is catching an error with try ... catch a better practice than catching an error with proper analysis/error check? For instance, removing from an empty list: Does surround with a try catch clause considered as a more efficient way than testing if the list is empty beforehand?Or is it the same? Thanks.

P.S: If a similar question was previously asked on the forum please feel free to refer it.

4
  • I think contrasting exception handling with "proper analysis/error check" might possibly be seen as just a tiny bit slanted. Apr 10, 2012 at 6:03
  • Well, there are cases where there is no comparison between the two, but I can think of some cases where they converge. For instance, let's take an illegal casting in java, I can either let it fail and catch the exception or I can check whether the element I'm about to cast is an instance of the casting class. Now, which solution appears to be better practice. Apr 10, 2012 at 6:11
  • 1
    possible duplicate of if/else statements or exceptions
    – vartec
    Apr 10, 2012 at 11:21
  • 1
    @fabricemarcelin: It depends: If in your worflow the object has to have a certain type and nothing else, then an exception is appropriate. If your code permits other types, do the check and don't wait for the exception. I prefer coding styles that avoid exceptions generally, by layouting a good program flow. That makes for a robust program and less headaches.
    – Falcon
    Apr 10, 2012 at 11:30

5 Answers 5

5

You should not handle the normal program flow via Exceptions. Exceptions should only be handled if you want to do something with it. If removing an element of an empty list should throw an exception, you should let it throw. If you want to return a new empty list from this method, you should do that.

There is not 1 absolute answer on this matter, you should check it per use-case.

Of course, it never hurts to do some defensive programming and making sure users don't see too much exceptions in the use of the application. In the example you mentioned, I would probably do a null-check and depending on the method, maybe throw a new ArgumentNullException. A try-catch in this situation just feels a little 'dirty' in my opinion, but in a bigger scenario it might make more sense.

Back in the days I've learned throwing exceptions is an expensive operation (random link, check bottom of the page), so avoid them if possible.

Another thing which I don't really like about catching errors is, if you don't narrow them down enough, you could potentially catch an error which doesn't have anything to do with the piece of code you really want to check. For example, if your application is 6-layers and you are calling some method like:

try
{
  otherlayer.Method1();
}
catch(IOException ioEx)
{
  //DoSomething
}

It is possible this IOException catches something which you didn't expect at first, so you will probably handle it wrong. (could happen if someone decides to change the other layers without your knowledge).

In summary: I would advice against using a lot of try...catch blocks in your code, only when they are really necessary and they are adding something usefull, or make sure your program flow will continue to operate.

5
  • +1: good answer but -1: Exceptions are not actually expensive! Constructing them is mildly expensive (but not expensive if compared to any code in an interpreted lang), and throwing them is cheap.
    – amara
    Apr 10, 2012 at 17:53
  • @sparkleshy: OK, I actually measured this once in C#. Using int.Parse vs. int.TryParse in C#. The first one wrapped in try-catch, the latter in an if-statement. The latter was by a major factor (I remember something like 10000x for the number of testruns) faster. So exceptions aren't that cheap and should be avoided in performance critical code on some platforms.
    – Falcon
    Apr 10, 2012 at 20:02
  • @Falcon: That's because it constructs an exception. To be fair, there are very few situations where you would actually want to throw a pre-built exception... but exceptions can be reasonably fast.
    – amara
    Apr 10, 2012 at 21:20
  • @sparkleshy: And why is construction expensive in a real world scenario? In C# you cannot even reuse an exception object. So what kind of argument is that? For further information: blogs.msdn.com/b/ricom/archive/2006/09/25/771142.aspx
    – Falcon
    Apr 10, 2012 at 21:28
  • Doesn't an exception always need to be constructed for it to be able to be thrown? I would expect null * 1 or throw new NullReferenceException() to be both expensive. I don't see how you can work with exceptions without them to be constructed (somehow). You've got an example (or link) perhaps?
    – Jan_V
    Apr 11, 2012 at 9:16
3

When to Check in Code

standard things like removing from an empty list, etc.

When to use Try...Catch

  • external access to networks
  • external access to file-system
  • external access to databases
  • etc
1

Much of what exception handling helps with is larger systems. In particular, code that detects an error may be several layers away (and written entirely separately from) the code that knows how to react to that error.

For a typical example, let's consider code for opening a file that's buried in some library. Just for simplicity, let's assume it's opening a file for logging. If the log can't be opened, that library code doesn't (and mostly shouldn't) know what to do. It should certainly detect the problem, but it has no idea whether (for example) you want to send out an email, display a MessageBox or NSAlert, etc. By throwing an exception, it let's the code that uses it to make the decision about how the problem is communicated to the user.

As for using an if statement and (for example) return value instead, we run into a similar problem. If we go this route, every layer from deep in the library where the file is opened, on up to the point that we display something to the user, has to cooperate in checking the error code and transmitting it up to a higher level if it something it can't handle itself. Unfortunately, in most cases, it's easier to do the wrong thing (make the call without even checking the return value) than the right one. Just for grins, let's say there are six layers of code between where the problem is detected and where the problem should be communicated to the user. Let's further assume there's a 90% of the programmer doing the right thing at each level. In that case, we get .96 = .53, or only a 53% chance that the error will actually be handled correctly. Even with (in my estimation) above average coding practices (I think 70-80% is probably closer to average) the chances of it being handled correctly are barely better than 50:50.

By contrast, with exceptions, code at intermediate levels doesn't have to do anything for the exception to be transmitted on up to where it can be handled (well, unless you're using Java checked exceptions, but if you do that, you deserve all the problems you get). Exceptions propagate by default instead of being "eaten" by default. We can simplify all the intermediate layers of code because the right thing happens by default.

1
  • Damn right. Exceptions are loved by most and hated by many for their ability to carry data and error information to the place where they should be handled without the need for global error lists or endless "pass errorcode"-cascades. In the empty list example, however, I firmly believe that the exception should be avoided in almost all use cases from occuring by doing a check beforehand. That's also the reason why I didn't upvote your post. You didn't really answer the questions in terms of good coding style etc. and when exceptions are appropriate.
    – Falcon
    Apr 10, 2012 at 11:25
1

Simple answer: Don't use try-catch for situations where you can check the failure condition in code.

Try-catch should not be used for controlling program flow.

See Vexing Exceptions - it's focussed on C# but is applicable to exception handling in all languages.

0

Is catching an error with try ... catch a better practice than catching an error with proper analysis/error check?

In 99.9% of cases, the shortest, simplest code is the best.

For instance, removing from an empty list...

If you are attempting to remove a specific item from a list, the item is either there or not there. There is nothing special about an empty list. Checking for an empty list is redundant, just as this if statement is redundant:

if (n > 0) {
  for (int i = 0; i < n; ++i) ...

If you test for the presence of the item, you will be duplicating the work about to be done by the 'remove' call. Don't do it. If the library function throws when the item is not present, go ahead and use try-catch. Consider extracting a new try_remove function that returns true when the item was removed and false otherwise.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.