CHAPTER 7 – PEAR ERRORS – Catching Errors
Unless an error handler that aborts execution is configured, the return value of a function failing with a PEAR error will be the error object. Depending on the error-handling setup, some kind of action may have been taken already, but there is no provided way of telling. One of the code design implications of this is that PEAR error-handling defaults should always be set by the driving script, or the script that PHP started executing. If some included library starts setting up error-handling defaults or global resources such as INI entries, trouble awaits.
PEAR::isError() bool PEAR::isError(mixed candidate) This method returns true or false depending on whether candidate is a PEAR error. If candidate is an object that is an instance of PEAR_Error or a sub- class, PEAR::isError() returns true. Raising Errors In PEAR terminology, errors are "raised," although the easiest way of raising a PEAR error is returning the return value from a method called throwError. This is simply because throwError is a simplified version of the original raiseError method. PEAR uses the term raising to avoid confusion with PHP exceptions, which are thrown. The relative cost of raising a PEAR error compared to triggering a PHP error is high, because it involves object creation and several function calls. This means that you should use PEAR errors with care--keep them for fail- ures that should not normally happen. Prefer using a simple Boolean return value for the normal cases. This same advice is given in regards to using exceptions in PHP, as well as C++, Java, or other languages. When you use PEAR packages in your code, you need to deal with errors raised by the package. You can do this in one of two ways: whether you are in an object context, and whether your current class inherits the PEAR class. If your code does not run in an object context, such as from the global scope, inside a regular function or in a static method you need to call the PEAR::throwError() static method: <?php require_once 'PEAR.php'; if (PEAR::isError($e = lucky())) { die($e->getMessage() . "n"); } print "You were lucky, this time.n";
function lucky() { if (rand(0, 1) == 0) { return PEAR::throwError('tough luck!'); } } ?> When errors are raised with static method calls, the defaults set with PEAR::setErrorHandling() are applied. The other way of raising errors is when your class has inherited PEAR, and your code is executed in an object context: <?php require_once 'PEAR.php'; class Luck extends PEAR { function testLuck() { if (rand(0, 1) == 0) { return $this->throwError('tough luck!'); } return "lucky!"; } } $luck = new Luck; $test = $luck->testLuck(); if (PEAR::isError($test)) { die($test->getMessage() . "n"); } print "$testn"; ?>
When throwError() is called in an object context, defaults set in that object with $object->setErrorHandling() are applied first. If no defaults are set for the object, the global defaults apply, as with errors raised statically (like in the previous example).
PEAR::throwError() ([object PEAR::throwError([string message], [int code], [string userinfo]) This method raises a PEAR error, applying default error-handling set- tings. Which defaults are actually applied depends on how the method is called. If throwError() is called statically, such as PEAR::throwError(), the glo- bal defaults are applied. The global defaults are always set with PEAR::set- ErrorHandling() and called statically. When throwError() is called from an object context, such as $this->throwError(), the error-handling defaults of $this are applied first. If the defaults for $this are undefined, the global defaults are applied instead. If you are not intimate with the semantics of $this in PHP, you may be in for some surprises when using PEAR error defaults. If you call a method stat- ically from within an object (where $this has a value), the value of $this will actually be defined inside the statically called method as well. This means that if you call PEAR::throwError() from inside an object, $this will be defined inside PEAR::throwError() and refer to the object from which you called PEAR::throwError(). In most cases, this has no effect, but if you start using PEAR's error-handling mechanism to its fullest, you should be aware of this so you are not surprised by the wrong error-handling defaults being applied.
PEAR::raiseError() object PEAR::raiseError([string message], [ i n t c o d e ] , [ i n t m o d e ] , [ m i x e d o p t i o n s ] , [ s t r i n g u s e r i n f o ] , [ s t r i n g error_class], [bool skipmsg]) This method is equivalent to throwError() but with more parameters. Normally, you would not need all these extra options, but they may come in handy if you are making your own error system based on PEAR errors. mes- sage, code, and userinfo are equivalent to the same throwError() parameters. mode and options are equivalent to the same PEAR_Error constructor parame- ters (see the following PEAR_Error description). The two remaining parameters are error_class and skipmsg: string $error_class (default "PEAR_Error") This class will be used for the error object. If you change this to some- thing other than PEAR_Error, make sure that the class you are giving here extends PEAR_Error, or PEAR::isError() will not give correct results. bool $skipmsg (default false) This rather obscure parameter tells the raiseError() implementation to skip the message parameter completely, and simply pretend there is no such parameter. If skipmsg is true, the constructor of the error object is called with one less parameter, without message as the first parameter. This may be useful for extended error mechanisms that want to base everything on error codes.
The PEAR_Error Class The PEAR-Error class is PEAR's basic error-reporting class. You may extend and specialize it for your own purposes if you need, PEAR:isError() will still recognize it.
PEAR_Error constructor void PEAR_Error ([string message], [int code], [int mode], [mixed options], [string userinfo])
All PEAR_Error's constructor parameters are optional and default to the null value, except message, which defaults to unknown error. However, nor- mally, you do not create PEAR errors with the new statement, but with a fac- tory method such as PEAR::throwError() or PEAR::raiseError(). string $message (default "unknown error") This is the error message that will be displayed. This parameter is optional, but you should always specify either $message or $code. int $code (default 1) The error code is a simple integer value representing the nature of the error. Some PEAR error-based mechanisms (such as the one in PEAR DB) use this parameter as the primary way of describing the nature of errors, and leave the message for a plain code to text mapping. Error codes are also good in conjunction with localized error messages, because they provide a language- neutral description of errors. It is good practice to always specify an error code, if nothing else to allow for cleaner, more graceful error handling. int $mode (default PEAR_ERROR_RETURN) This is the error mode that will be applied to this error. It may have one of the following values: PEAR_ERROR_RETURN PEAR_ERROR_PRINT PEAR_ERROR_DIE PEAR_ERROR_TRIGGER PEAR_ERROR_CALLBACK The meaning of the different error modes is discussed in the following "Handling PEAR Errors" section. mixed $options This parameter is used differently depending on what error mode was specified: For PEAR_ERROR_PRINT and PEAR_ERROR_DIE, the $options parameter contains a printf format string that is used when printing the error message. For PEAR_ERROR_TRIGGER, it contains the PHP error level used when trig- gering the error. The default error level is E_USER_NOTICE, but it may also be set to E_USER_WARNING or E_USER_ERROR. Finally, if $mode is PEAR_ERROR_CALLBACK, the $options parameter is the call- able that will be given the error object as its only parameter. A callable is either a string with a function name, an array of class name and method name (for static method calls), or an array with an object handle and method name (object method calls).
string $userinfo This variable holds extra information about the error. An example of content would be the SQL query for failing database calls, or the filename for failing file operations. This member variable containing user info may be appended to with the addUserInfo() method.
PEAR_Error::addUserInfo() void addUserInfo(string info) This variable appends info to the error's user info. It uses the character sequence " ** " to separate different user info entries.
PEAR_Error::getBacktrace([frame]) array getBacktrace([int frame]) This method returns a function call backtrace as returned by debug_backtrace() from the PEAR_Error constructor. Because PEAR_Error saves the backtrace before raising the error, using exceptions through PEAR errors will preserves the backtrace. The optional integer argument is used to select a single frame from the backtrace, with index 0 being the innermost frame (frame 0 will always be in the PEAR_Error class).
PEAR_Error::getCallback() mixed getCallback() This method returns the "callable" used in the PEAR_ERROR_CALLBACK error mode.
PEAR_Error::getCode() int getCode() This method returns the error code.
PEAR_Error::getMessage() string getMessage() This method returns the error message.
PEAR_Error::getMode() int getMode() This method returns the error mode (PEAR_ERROR_RETURN and so on).
PEAR_Error::getType()string getType() This method returns the type of PEAR error, which is the lowercased class name of the error class. In most cases, the type will be pear_error (in lower- case), but it varies for packages that implement their own error-handling classes inheriting PEAR_Error.
PEAR_Error::getUserInfo() string getUserInfo() This method returns the entire user info string. Different entries are sepa- rated with the string " ** " (space, two asterisks, space).