RE: this is the life :)
| From: | David Ashwood | Date: | Sun, 11 Jul 2004 09:37:19 +0000 |
| Subject: | RE: this is the life :) | ||
| References: | 1 | Groups: | php.pear.dev |
| Request: | Send a blank email to pear-dev+get-31845@lists.php.net to get a copy of this message | ||
Just an idea - but what if you could do something like:
<?php
$t = false;
...
try {
$tt = $obj->doSomething();
$another = $obj->doFollowup();
} catch ((Exception $e) or (PEAR::catchAllErrors(E_STRICT OR E_WARNINGS)
$e)) {
if ($t) {
// handle the exception
}
}
echo 'hello';
?>
Where PEAR::catchAllErrors(E_STRICT OR E_WARNINGS) would raise an exception
due to $tt not being defined. If catchallErrors() could be defined through a
DEFINE("ErrorLevel", E_STRICT OR E_WARNINGS); - you could use one setting
during development/debugging and one for deployment.
I know this isn't the way things are done now, or even how exception
handling is generally done with Try/Catch - but it would enable stronger
error handling - should you wish to implement it.
The problem with Try/Catch - is that the catch is only done should a throw
be encountered during a statement - rather an evaluation of the catch
statement after the code has run.
I haven't looked at PHP5 exceptions much - but you could implement the
PEAR:catchAllErrors() in a finally statement:
Something like:
Try {
// Do something
} catch (Exception $e) {
// Handle normal throw statements
} finally {
Switch ($e=PEAR::catchAllErrors()) {
Case x:
Break;
Case y:
Break;
Default:
Break;
}
}
Also the catch statement (in all cases should be in the form:
catch ((Exception $e) or (PEAR::catchAllErrors(E_STRICT OR E_WARNINGS) $e))
{
switch ($e) {
case Exception_VariableUndefined:
echo "Variable {$e['errorDetail']}";
break;
case UserExceptionSomethingMessedUp:
echo "Fatal Error During connection to something";
break;
default:
// Something unexpected
Throw $e;
break;
}
}
Just my thoughts on the subject.
David
david@inspiredthinking.co.uk
-----Original Message-----
From: Greg Beaver [mailto:cellog@php.net]
Sent: Saturday, July 10, 2004 9:49 AM
To: pear-dev@lists.php.net
Subject: this is the life :)
Hello all,
Returned from our successful concert in Massachusetts at 2 AM, read
email, posted a large new section on design issues to think about with
exceptions on the wiki.
One easy way to summarize the mistakes I see in espousing exceptions:
when looking for a better way to do things, design for the worst
possible use, not the best.
PEAR_Exception is an excellent example of designing for the worst
possible use. Exceptions at their worst are completely internal, do not
even notify outer levels that anything wrong has happened, leap all over
the place, and are generally impossible to debug. PEAR_Exception can
actually help correct a series of spaghetti code decisions through
observers. In other words, it is possible to look at the PEAR_Exception
hierarchy in your code as it is written (throw within try/catch), or as
a flat hierarchy of sequential exceptions as seen by observers - and
even caught exceptions are seen.
In other words, contrary to popular belief, exceptions do not force you
to handle an error.
<?php
try {
throw new Exception('see?');
} catch (Exception $e) {
}
echo 'hello';
?>
Surely, no one but an idiot would write the above code (grin), but the
point is PHP will not display any error message whatsoever if you do
happen to write this. A more realistic example:
<?php
$t = false;
...
try {
$tt = $obj->doSomething();
$another = $obj->doFollowup();
} catch (Exception $e) {
if ($t) {
// handle the exception
}
}
echo 'hello';
?>
This is still bad design since there should be 2 try/catch blocks in
this case, but it looks better. Inexperienced users WILL write code
like the above, and it will most likely work in most cases. However,
the 1 typo ($tt = ...) may not be caught for a long time.
PEAR_Exception allows users (to a certain extent) to actually find this
bug by setting an observer that prints out every created exception, and
then noticing that an exception is being raised in doFollowup(), but is
not being properly handled in the catch clause. It doesn't improve the
design, but does improve the resulting code.
This must be the goal of any error handling system. Help find and
remove errors in both the code and in the user's input. The only way to
do this is to provide flexibility in error severity as well as flow
control. throw provides excellent flow control flexibility, but
absolutely no severity flexibility beyond "catch this or die."
The exception class, on the other hand, through its use of OO, is very
flexible, and does provide a great way to implement flexible error
severity. I whipped up a proof-of-concept class that just might solve
the problems ErrorStack (now PEAR_ErrorStack) was built to solve, and it
is compatible with PEAR_Exception. This means there is a possibility of
converting a warning directly into a standard exception by simply
throwing it.
I leave again on Sunday, but in the mean time, let's have some fun. :)
Greg
P.S. I also converted PEAR_ErrorStack into E_STRICT to see how hard it
was, and could commit it as PEAR_ErrorStack5.php if there is interest.
The API is identical, only the internals have changed, so the classname
remains PEAR_ErrorStack.