Error handling in PEAR can be used to make error messages on your development machine more verbose, while keeping them short for your visitors without much hassle.
When you develop some code on your machine you usually want all information on the errors you get.
Contrary to that you don't want to reveal all this info to the everyday website visitor. Besides the fact that they usually won't understand it there are people who just wait to see something like that and get inside information that may make your site vulnerable to attacks.
You can echo out variables or use
print_r for structures like arrays. The problem
with that is you have to delete all this code
when you update your site and next time when something fails
write it again.
PEAR code has a simple yet very useful way to pass errors - through error objects that are instantiated when something fails. If you have looked at the example code from the PEAR manual you've already seen how to use that when a database query fails for example. The example shows:
if (DB::isError($result)) {
die ($result->getMessage());
}
The getMessage() method returns a short message
describing the error, like DB Error: syntax error for example.
Surely this can help but usually you'll want to see the query which caused the error,
the old way to do that was to start looking in the sources until
you find the piece of code which cause the error and then
echo out the query.
When the PEAR_Error object is instantiated the parameters
it takes are:
The developer info contains the failed query along with the error message from the database server. Example:
SLECT * FROM mytable [nativecode=1064 ** You have an error in your SQL syntax near 'SLECT * FROM mytable' at line 1]
This info can be fetched by the getUserinfo() method but
again you go into changing code just to find a failing query.
You are already displaying messages with the getMessage()
method so you need just to change things on your side only
to get the user info too.
To accomplish this you need to modify the getMessage()
method of the PEAR_Error class. It is defined in the source as:
function getMessage()
{
return ($this->error_message_prefix . $this->message);
}
This can be found in the PEAR.php file in your PHP
extensions directory, usually /usr/local/lib/php/ on Unix.
Search it and then replace this code with:
function getMessage()
{
return ($this->error_message_prefix . $this->message .
'<br />' . $this->userinfo);
}
The next time a query fails you will see it displayed along with the almost useless default message.
With the PEAR error handling you can even get rid of all that manual checks
whether the query failed by setting an appropriate error mode. The default mode
called PEAR_ERROR_RETURN doesn't do anything but just quit the
function that triggered the error. If you want to change the default for all PEAR
objects you just add PEAR::setErrorHandling(mode); to the top of
your code (after PEAR.php is included but before any PEAR object
is created).
The mode can be PEAR_ERROR_DIE if you want the same
messages as from the getMessage method or you can define your
own custom function and use it with PEAR_ERROR_CALLBACK like
PEAR::setErrorHandling(PEAR_ERROR_CALLBACK, 'my_function');.
Your function accepts an error object which has properties like code,
message and userinfo. An example function follows.
function handlePearError($error) {
echo "$error->message<br />n",
$error->userinfo;
exit;
}
If you want to use it on a public server just remove the line which displays
$error->userinfo.
If you need to temporarily set the error handling for an object you can do
$db->pushErrorHandling(mode); and after you're done restore
the previous setting with $db->popErrorHandling();, assuming that
your object is called $db.
Comments
thanks for (push|pop)ErrorHandling
thanks for the tip about pushErrorHandling() and popErrorHandling(). These handy little tools don't seem to be documented at http://pear.php.net/
PEAR Error Insights
Thanks for writing up what you have
learned about PEAR error handling. The
PEAR site makes quite an ado about this
feature, yet lacks concrete examples
that provide real world benifits.
After I found how good the feedback is
that can be obtained, while trying to
figure out what was wrong with a QuickForm to DB's autoexecute(), in
seconds I had solved the programming
problem. Then I went in search of
information.
That is when I found you site and some
extra nuggets of wisdom to tuck away.
Thanks...
Jim Tom Polk