[LRUG] Exceptions as a flow control mechanism

Daniel Tenner daniel.ruby at tenner.org
Wed Dec 19 04:37:57 PST 2007


Agreed with Tim.

To add another example, I'm working on an API for a Flex client, and  
having centralised exception handling is extremely useful, since I  
need to render the exceptions as special objects so that they are  
picked up by Flex. In fact, it's so useful I've even implemented a  
little patch to ActiveRecord (which I need to remember to submit!...)  
that allows me to make the find_by_xyz... methods also throw an  
exception when no record is found (by adding a ! after the method  
name). This way all the 'record not found' exceptional cases are  
dealt with in a centralised, DRY, user-friendly way.

Basically, you have a flow of steps in your controller. They depend  
on a number of objects being located. You have two options to deal  
with objects not found:

1) the old, exception-less way of peppering your code with multiple  
if statements
2) the modern, effective way: write the code as it should work and  
let it throw exceptions when something goes wrong

Once seen from this perspective, it makes a lot of sense, imho, to  
make it easy to centralise that exception handling.

Also worth bearing in mind - the main reason why Exceptions are  
usually discouraged for flow control is because they are expensive to  
throw and catch. This is a problem when you're using an exception to  
control the flow of something small, like a loop. E.g., in Java:

try {
   Iterator it = array.iterator();
   while (obj = it.next()) {
     // do something
   }
} catch (NoSuchElementException e) {
   // let flow continue
}

Using exceptions for this kind of flow control is discouraged because  
the exception handling takes a lot more time than the typical  
iterator loop.

However, when you're looking at an HTTP request to a database-backed  
web server, the typical latency being in hundreds of milliseconds,  
the fact that the exception costs an additional 0.2ms to generate  
compared to creating a quagmire of if statements is irrelevant... You  
could thrown an exception in every single request and probably barely  
see the difference.

</$0.02>

Daniel

On 19 Dec 2007, at 12:22 19 Dec 2007, Tim Harding wrote:

> I guess it all comes down to how you define exceptional.
>
> The argument put forward for find(params[:id]) throwing an  
> exception in the first place is that if you're looking for a  
> particular record and it isn't there then you probably had good  
> reason to expect it to exist, there was a link to it or whatever.  
> It would be pretty surprising if your app linked to a record that  
> didn't exist. That's exceptional according to the Rails framework.
>
> If you try to find(:all) then you're looking for a set and an empty  
> set is a normal kinda set, returning an empty collection is  
> unexceptional.
>
> They're basically equating record not found to page not found here.
>
> Perhaps it all comes down to how your app is specified to handle  
> record not found, if there's something actually useful you can do  
> on RecordNotFound that will help the user then handle the exception  
> where it is raised. If there are reasonable decisions you can take  
> in each different instance then global exception handling isn't  
> very useful.
>
> If you're working on a CMS and an :id actually represents a page  
> then being able to declare what should happen to RecordNotFound,  
> i.e., presenting a 404 is actually remarkably useful and saves a  
> whole lot of worry about letting things slip through the gap.
>
> What do you do to handle a record not found in your app?
>
>
> On Dec 19, 2007 4:50 AM, James Adam < james.adam at gmail.com> wrote:
> I think we've talked about this before, but Rails 2.0 has taken a
> stance so I thought it might be interesting to pick the "Best Minds In
> London" (i.e. you filthy lot) about the use of exception handling as a
> form of flow control.
>
> I'm talking about this:
> http://almosteffortless.com/2007/10/08/graceful-404s-in-rails-20/
>
> Which is, to summarise, advocating throwing an exception when, say,
> you can't find a particular record with that ID, and then letting some
> Rails magic pick up the pieces and run a method accordingly.
>
> I'd always thought that exceptions shouldn't really be used for this,
> although I don't have a particularly solid justification for this
> belief. Am I wrong? What do you think?
>
> Actually, here's the quote, and I take issue with a different aspect
> of it here too:
>
>  "Lots of common exceptions would do better to be rescued at a shared
> level rather than per action. This has always been possible by
> overwriting rescue_action_in_public, but then you had to roll out your
> own case statement and call super. Bah. So now we have a class level
> macro called rescue_from, which you can use to declaratively point
> certain exceptions to a given action."
>
> Surely "rescue_action_in_public" was only there to handle unforseen
> catastrophic errors? It seems like massive overkill/folly for anyone
> to try and use this to handle ActiveRecord::RecordNotFound, right?
>
> --
> * J *
>  ~
> _______________________________________________
> Chat mailing list
> Chat at lists.lrug.org
> http://lists.lrug.org/listinfo.cgi/chat-lrug.org
>
> _______________________________________________
> Chat mailing list
> Chat at lists.lrug.org
> http://lists.lrug.org/listinfo.cgi/chat-lrug.org

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lrug.org/pipermail/chat-lrug.org/attachments/20071219/025f9d19/attachment-0003.html>


More information about the Chat mailing list