So I’m reading The Daily WTF and they have this horror story. I’m paraphrasing in pseudocode:
if not customer.isActive():
throw RedirectException("/support/accountdisabled/")
else if ...
OK, see, what happens here is that the programmer raises an exception to control the flow of the code. Exceptions are meant to be errors and shit like that.
“This is not really a big deal,” I think to myself. Go through the comments, and people are in shock and awe. Uh. Let me explain to you why this has absolute merit and why I do this myself several times a day.
—
When you return something from your method, that obviously gets returned to whatever was calling you. Crucial piece of programming logic, there. Well, what if I’m building a web framework where I have some code sitting in my core to handle headers and what-not, and to deal with actual content and requests, I outsource that to, like, handlers, that the developer can write, if they use my awesome framework. Now if I want to redirect, I have to return a special object back from my handler, call it HttpRedirect, or something.
Now this is where “correct code” really steals my peach. Say that I do some elaborate magic in my handlers, and the redirection might—in fact—be handled by another method called by my handler. What then? “Oh, just return the result of the call to that method,” you say. Like this:
function myhandler():
return somefunc_thatmightreturnaredir()
O…kay. Uh. Well. I guess I have to make sure that somefunc_ doesn’t .. wait, no. I don’t want to return if it’s not a redirect. So lets just check whether the type of the returned value is a HttpRedirect! Well, what if somefunc_ calls another method that might potentially redirect? Then I have to move all my logic into somefunc_ as well, right? Or do a return-loop all through that flow, and I basically end up moving the step up one from the core web framework to my own handler. I guess you could quickly whip up a method named maybeRedirectIfReturnValueFromTheThingIJustCalledHasTheCorrectType and reuse this throughout your code, but that’s just fucking stupid.
What if my web framework comes with some authentication kit you can use, and this framework happens to do some redirection on its own? If this is not the correct behavior for your app and you want to intercept it, you’re out of luck.
You startin’ to see where I’m getting at?
—
Here’s the stupid programming trick: Exceptions are like a chain reaction. They burn through the fuse you’ve laid out through all your method calls and your code has every opportunity to catch it before it reaches the gunpowder barrel and your program explodes—it raises an exception and displays that to the user, or something. Not what you want, anyway.
Now why is this so god damn immensely useful to you as a programmer? Because you don’t have to return-link anything, no race conditions, no repetitive logic throughout your code.
In my example from before, in my core web framework, I’d simply do this:
try:
result = handler(request)
print result
except HttpRredirect, redir:
print "Location:", redir.url
Cool, eh? This is more stable functionality in your app than any kind of return-linking, type-checking hell you can come up with. I do this all the fucking time, and it works really well.
Oh, this is common practice in CherryPy and you should also read Pylons FAQ: Why do redirect_to and abort raise exceptions, instead of returning a Response?.
But then that’s just me. What about you, do you think exceptions have legitimate use outside traditional error handling?