Re: Try Catch
| From: | Tomas V.V.Cox | Date: | Sat, 21 Jul 2001 12:21:58 +0000 |
| Subject: | Re: Try Catch | ||
| References: | 1 2 3 | Groups: | php.pear.dev |
| Request: | Send a blank email to pear-dev+get-904@lists.php.net to get a copy of this message | ||
Oleg Rekutin wrote:
>
> ed@belsoft.vitebsk.by (Ed V. Bartosh) wrote in
> news:858zhjqjet.fsf@bartosh.org:
>
> > /Fri, 20 Jul 2001 15:55:51 -0700/ you wrote:
> >
> > RK> Do we have a Try Catch in PHP?
> >
> > RK> I'm tired of
> > RK> if ( PEAR::isError (
>
> No try/catch, no exceptions support, no goto to fudge it either. I've spent
> a long time trying to figure out how to emulate exceptions or alleviate the
> pain of if (PEAR::isError(, but failed to come up with a solution.
> > Use callbacks instead:
> > PEAR::setErrorHandling(PEAR_ERROR_CALLBACK, ...
>
> Callbacks are not enough because they are triggered when the error is first
> thrown and cannot alter the control flow. This means that the code cannot
> add extra information as the error 'bubbles up' (small concern, but still
> useful) or handle errors selectively (say DB raises one error that certain
> code can fix, but the rest of DB errors are lethal... with a general
> callback, once the error is thrown, the code that was able to fix the
> problem will not be reached).
> Perhaps that last point was unclear... Example, emulated MySQL sequences in
> PEAR DB. If sequence was never created, attempting to retrieve the next id
> results in a DB_Error thrown inside of DB_mysql::nextId(). However, nextId()
> checks whether the error is 'no such table' and if so, attempts to create
> the sequence, and then tries again to retrieve the next ID. If a callback is
> registered, then the execution will stop when nextId() fails to obtain the
> first ID, even though it knew how to recover.
> In my current application, I just made a keyboard shortcut for if
> (PEAR::isError($result)) return $result, which is what I do in almost all
> cases, with the exception of where I actually handle received errors.
>
With this simple code the problem can be solved. "Try" this:
<?php
require_once 'DB.php';
// use (&$mixed) when Zeev fix the problem
// with objects by reference :)
function try($mixed) {
if (DB::isError($mixed)) {
$GLOBALS['DB_exeption'] = $mixed;
return false;
}
return true;
}
function mydie() {
$error = &$GLOBALS['DB_exeption'];
if (!empty($error)) {
die ($error->getMessage()."\n".$error->getDebugInfo());
}
}
$dsn = 'pgsql://postgres@localhost/sexogratis';
try($db = DB::connect($dsn)) or mydie ();
echo "connected\n";
try($id = $db->nextId('sequences')) or mydie();
echo "seq id: $id\n";
?>
try() will catch the error, store it in a global var and return false.
This is detected by the "or" condition and call mydie() that will raise
the catched error and finally abort the execution.
Perhaps the best solution could be to provide a system whithin all DB
functions that use internal DB functions don't use the global error
handler and treat the error by them selves. But I think that only very
few functions are affected by this problem (only nextID/createSequence
?).
Tomas V.V.Cox