Re: Common way of error handling?
| From: | Ulf Wendel | Date: | Sat, 13 May 2000 18:32:25 +0000 |
| Subject: | Re: Common way of error handling? | ||
| References: | 1 2 3 4 | Groups: | php.pear |
| Request: | Send a blank email to php-pear+get-103@lists.php.net to get a copy of this message | ||
Sterling Hughes wrote:
>
> Ulf Wendel wrote:
> >
> > +++ API +++
> >
> > He're an API demo of the sketched modell:
> >
> > <?php
> > class my_pear_module {
> > function createNotice() {
> > new pear_notice("my_notice");
> > }
> >
> > function createWarning() {
> > new pear_warning("my_warning", 1000, __FILE__, __LINE__);
> > }
> >
> > /**
> > * @return bool $ok
> > */
> > function createError() {
> > if (true) {
> > $err = new pear_error("my_error", 1, __FILE__, __LINE___, false);
> > $err->show();
> > return false;
> > }
> > return true;
> > }
> > }
> >
> > my_pear_module::createNotice();
> > my_pear_module::createWarning();
> > my_pear_module::createError();
> > ?>
> >
> > The class hierachie is pretty simple (as shown above). It takes less
> > than 200 loc in PHP, it's flexible and can be configured widely. It does
> > not come with major restrictions. How about it?
> >
> > Ulf
> >
>
> >From what I see and understand, I like it. However, I'd like a concrete
> example of how it might be used within PEAR and then how the user would
> catch the error (I saw the example above, I'm just asking for a more
> concrete example.)
>
> Sterling
The way you use it within PEAR is sketched above. Critical is the
question how the user can catch an error thrown by a module. Java knowns
a try-catch construct, which PHP does not know:
try {
[...]
} catch (NameOfException) {
[...]
}
In case of an exception the catch block tries to handle the exception.
How could this be translated in PHP code?
In the DB module Stig made the decision that a function can have several
return types. If it's a negative integer from -1 to -999 it's an error
occured. If it's less than -999 a warning is thrown. The user writes
something like this:
<?php
$obj = DB::factory();
if (!is_object($obj))
print $db->ErrorMessage($obj);
?>
This works fine as long as you don't have functions that return negative
integer values. By the way I don't like the idea that return types
suddenly change.
Another point is that each module has to provide certain functions to
deal with the exceptions. In DB you can find isError(), isWarning(),
ErrorMessage() and lots of define calls. Does every PEAR module provide
these functions, could we derive every PEAR module from a PEAR base
class where these functions reside? Yes, we could, but it does not solve
the underlying problem.
How does PHP itself handle this situations? PHP sometimes stops
execution, sometimes returns false and sometimes return 0 or "" or an
empty array. It always displays an error message unless you supress it.
I think we can't do better but simulate this behaviour.
With the sketched modell it's up to the module designer which way to
take.
+++ throwing exceptions that can't be caught +++
class foo {
/**
* @return int $foobar
*/
function bar() {
[...]
if (false == $ok)
new pear_notice("Note from bar()", 1, __FILE__, __LINE__);
[...]
return $foobar;
}
}
$foobar = foo::bar();
This notice can't be caught, but the user can override
pear_exception_handler::handleNotice() to define what happens with the
note.
+++ throwing exceptions that can be caught +++
class foo {
/**
* @return mixed $foobar returns an integer on success, an error
message on failure
*/
function bar() {
[...]
if (false == $ok) {
$err = new pear_warning("Warning from bar()", 2, __FILE__,
__LINE__, false);
return $err->get();
}
return $foobar;
}
}
$foobar = foo::bar();
A warning is created, but not automatically handled. Usually it would be
display on the screen, the script would continue.
+++ throwing exceptions that stop execution +++
class foo {
/**
* @return int $foobar
*/
function bar() {
[...]
if (false == $ok)
new pear_error("Panic!", 3, __FILE__, __LINE__);
return $foobar
}
}
$foobar = foo::bar();
An error is created and automatically handled. The message would be
displayed, excecution stops.
+++ what can be modified by the user? +++
The user can override the default behaviour of any kind of exception.
He might want to change the way a warning is displayed and send the
warning via e-mail. To do so the user writes a new method
pear_warning::handleWarning() and overrides
exception_handler::handleWarning().
<?php
function handleWarning() {
if (!$this->show_warning)
return;
$msg = sprintf("s***, there's a warning in %s (line %d): '%s'",
$this->file,
$this->line,
$this->message
);
@mail("ulf@redsys.de", "warning in ".$this->file, $msg);
print $msg;
if ($this->halt_on_warning)
die();
}
?>
Maybe the user wants that script excution always ends, even on notes. To
do so you the user defines an instance var pear_notice::halt_on_notice
and sets it true to override pear_exception_handler::halt_on_notice.
As you can see it's not perfect, but it's a good compromise.
We would get rid of:
- lots of defines
- error handling functions within a module
We would get:
- five basic exception (notice, warning, error, io, runtime)
- default behaviours
- configurable behaviours
Ulf