[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