Sign in
in
   
"It is the mark of an educated mind to be able to entertain a thought without accepting it."  -Aristotle

About Me

I am a co-founder of Notches, an early stage startup currently based in NYC. We are building a free, open reviews network that anyone can participate in and anyone can build on top of. You can find out more on our official blog.

Read more about my background.

Connect with me on...

Recent Readers

Flickr Photos

 

Warning:

This article is more than 45 days old. Given the speed at which the technology world moves, this post is probably somewhat out of date. Please keep this in mind when reading the post. If this is a tutorial, please check whether you are using the same versions mentioned in the article.

Managing Exceptions in Framework Code

One of the long-running debates here has been the use of exceptions for managing workflow. This was especially fierce while we were working on the Javascript framework, but it has died down a little in the strongly-typed .NET world.

The two major questions are:

... when should should you return false / null and when should you throw an exception?

I've always been of the opinion that a method should only throw exceptions for events that are truly fatal. For example, a search method returning no results is not an exception. However, a method that internally uses that search method may throw an exception under certain scenarios if it was intending on operating those results.

Others are of the opinion that everything should be thrown as an exception. The argument is that even something like no results should trigger exception-handling code, and the easiest way to do this is have the callee fall into a catch block.  ( I would counter that, even in the catch block, you need to special case different scenarios, so why "pretend" that something is an exception? To me, it seems clearer what's going on )

... should the framework ever handle an exception itself, or always throw to the callee?

Generally, anytime something is truly an exception, I think it should be re-thrown. However, there are cases based on how the code may be called that necessitate handling the exception.  One scenario we dealt with in terms of our Javascript framework was with asynchronous callbacks. If an exception occurs, there is no application code to rethrow it into, so we must either handle it ourselves or get an ugly "exception thrown and not handled" dialog.

It helps if you can dynamically determine whether there is an appropriate callee, which we are able to do in .NET and potentially in Javascript as well.

So... What's your best practice / opinion?

Only published comments... Jan 04 2006, 08:00 AM by Tim

View related posts

 

Omer van Kloeten said:

I will throw an exception unless one or more of the following conditions is met:
1. The method will be called many times in sequence - simple performance consideration.
2. The method will be called as part of a larger algorithm's condition, such as when using 'if (Double.TryParse(x, out y)) { /* It's a number, keep working */ } else { /* Not a number, work accordingly */ }' in contrast to 'Double.Parse(x); /* Argument checked, now let's get on with things */'.
3. The caller is outside .NET (such as when exposing COM interfaces, exposing web services, etc.).

I might have forgotten several bullets, but when it gets right down to it, it's mostly intuition.

The only time you should wrap an exception with your own is when you have to handle the exception. Otherwise, let it propegate automatically.
You should always wrap an exception if you think you are able to explain the problem better than the original exception, as is when writing components that will be used as black-boxes.
Of course that the first layer of calls should always handle all exceptions so that they don't propegate beyond the application as unhandled exceptions.
January 4, 2006 11:32 AM
 

Josh Einstein said:

My rule of thumb is: If the exception is "ignorable" then return null/false/default(T)/etc. If you expect that something may happen, that's not an exception then is it?

For example. When I deserialize the settings object in TEO, I know that there may be many reasons why deserialization fails. If the file doesn't exist it's because settings have never been saved and therefore that's not an exception. In this case, I simply construct a new settings object with defaults. If the file is tampered with, and can't be deserialized properly, then that's an exception. I throw the exception but then I catch it, log it, and still make the new default settings object. But the caller to ApplicationSettings.Current will never see that exception because they shouldn't have to.
January 31, 2006 7:14 PM