Re: PEAR_Error and Error_Stack

From: Date: Wed, 03 Mar 2004 03:48:49 +0000
Subject: Re: PEAR_Error and Error_Stack
References: 1  Groups: php.pear.dev 
Request: Send a blank email to pear-dev+get-26046@lists.php.net to get a copy of this message
Hi Jesus, Jesus M. Castagnetto wrote:
The singleton pattern might be simpler to implement in PHP 5 using a static property, but the global instance should be more transportable. If the package is accepted, once channels are implemented, I would release a PHP5-only version that takes full advantage of PHP 5 while retaining the same API. This would mean much more advanced stuff will be used across the board, and no global variables.
The error handler registration, reminds me of the use of events-eventListeners in other langs, with the difference that in Greg's code the listeners are pushed/poped from a stack, so it is not as easy to remove a given listener from the middle w/o several pop/push. Maybe using named error handlers and an assoc The intended purpose of push/popCallback is not to allow listening, but instead to allow silencing of internal errors, or automatic repackaging of internal errors. I pretty much assumed that the separation of logging and error callback would allow listeners to be registered as log objects. Of course, the current implementation forces the log object to be a PEAR::log, but if PEAR::Log releases a PHP5 version that has an interface I could instanceof, this would simplify things a bit.
Is there a scenario I haven't thought of that would benefit from another model? I did include the ability to set a default error callback just in case you do want a global listener, maybe that works for the scenario?
array?, e.g instead of pushing to the $_errorCallback just assign something like: $_errorCallback[$cbName] = $cb;? Not sure how often one will register (push) or deregister (pop) callbacks during the lifetime of a running script, so it is just a possible idea. Overall I like the class, it is lightweight and can be used instead of PEAR_Error more portably across PHP versions. To make use of its full power it will require chaging the old test of PEAR::isError() to checking if there is an error in a given error stack (perhaps a convenience static method for that?). In my mind, I thought I had programmed a "staticHasErrors" method, but it appears that I didn't :). I did program staticGetErrors(), and this static method returns an array of all errors, either sorted in the order of their occurrence, or sorted by package and order of occurrence
http://www.chiaraquartet.net/Error_Stack/Error_Stack/Error_Stack.html#methodstaticGetErrors This would be a possibility if (Error_Stack::staticHasErrors()) { } or if ($instance->hasErrors()) { } for a single Error stack. I'm not fond of PEAR::isError(), it is a replacement for try/catch. I would probably implement isError() through the use of a property and a callback function errorCallback($err) { if (!in_array($err['level'], array('debug', 'info', 'notice', 'warning'))) {
       $this->_exception = true;
} } ... $this->stack->pushErrorCallback(array(&$this, 'errorCallback')); ... $this->doSomething(); if ($this->_exception) { return; } To me, that reads much cleaner. However, there may be a much better way to do this, and I will keep the stability of the package alpha or beta until it has had lots of field testing. One idea I'd love some feedback on is how to repackage legacy application errors. What I'm thinking is that many applications use the dreaded PEAR::raiseError() all over the code, instead of defining an instance method. If an instance method is defined, it is simple to repackage the PEAR_Errors with no BC breakage: class myDB extends DB { function myDB($params) {
         Error_Stack::singleton('DB', false, false, 'Error_Stack', true); // return PEAR errors, but put them on the stack first
} function raiseError($someparams) {
       return Error_Stack::staticPush('DB', )... etc. etc.
} } If the package uses PEAR::raiseError(), the only way to repackage is with a callback function handlePEAR_Error($err) { if (is_array($info = $err->getUserInfo()) && isset($info['package'])) {
      return;
      // this is a Error_Stack re-packaged PEAR_Error
} Error_Stack::staticPush('unknown', $err->getCode(), 'error', $err->getMessage())... etc. etc. } PEAR::setErrorHandling(PEAR_ERROR_CALLBACK, 'handlePEAR_Error'); Of course, if you know all of the error messages of the package, you could make the callback smart enough to repackage them in the correct package based on the message, but this could be a very expensive operation, both in terms of execution and number of lines of code. This would not be an issue for many of the larger packages, so perhaps the solution would also be to release an intermediary version of the package that uses the compatibility of returning a PEAR_Error through Error_Stack::staticPush(). Comments? Greg

« previous php.pear.dev (#26046) next »