Re: Exception misinformation
| From: | Sergio Carvalho | Date: | Tue, 06 Jul 2004 23:09:03 +0000 |
| Subject: | Re: Exception misinformation | ||
| References: | 1 2 3 4 | Groups: | php.pear.dev |
| Request: | Send a blank email to pear-dev+get-31681@lists.php.net to get a copy of this message | ||
Justin Patrin wrote:
Attachment: [application/pgp-signature] OpenPGP digital signature signature.asc
Ugly, but doable It would make more sense to put these in nested if/else blocks. You could also do nested try/catch, but that makes things even harder to read. I suppose it's no worse than the if/else stuff....Naturally. It's that I'm not a big fan of highly nested control structures. They look awfull, Exceptions or no Exceptions. A truly OO, better looking equivalent would be: foreach($dataSources as $dataSource) {
if (!isset($data)) {
try {
$data = $dataSource->fetch();
} catch (Exception e) {
// Handle exception, probably just log it
}
}
}
if (!isset($data)) thrown new Exception('...');
However, I was trying to show that Exceptions don't inherently lead to hard-to-follow code paths. In fact, they can be used just like return codes. From the point of library usage, they're just about the same thing.
The difference comes when writing libraries, whenever the library is layered (or uses external libraries). With return codes, the upper layer must watch the return code of the lower layer, and re-return it. With exceptions, if the upper layer does nothing: the unhandled exception goes up the call stack looking for a handler. At most, we have rethrow code once, at the bottom of the method.
What happens, is that most methods in the middle layers look like this:
function foo()
{
try {
// Do our stuff. Only 'fixable' errors need to get caught in here
} catch (Exception e) {
// Something unfixable went wrong. Cleanup if needed and rethrow
throw new Exception('message', e);
}
}
Since we don't care about non-fixable errors (they get rethrown at the end), middle layer code (most code) is greatly simplified.
I still wonder about this, though, as many experienced coders say that Exceptions shouldn't be used for code flow handling.And they're correct. My personal rule is: write The One True Path thinking in terms of 'transactions' (try blocks) that may not get executed (just like in the data fetching example). The catch blocks should just arrange for cleanup, or rollback of the 'transaction'. For each try-catch, either all of the code executed, or none of it did (we rolled back in the exception handler). Then, the normal code flow, upon non-execution of a try block, must decide if it is correctable (fetch from another source, in our example), or bail out (throw an exception). Sérgio Carvalho
Attachment: [application/pgp-signature] OpenPGP digital signature signature.asc