Re: PEAR_Error, ErrorStack, Exception, and compatibility

From: Date: Wed, 23 Jun 2004 08:16:06 +0000
Subject: Re: PEAR_Error, ErrorStack, Exception, and compatibility
References: 1 2 3 4  Groups: php.pear.dev 
Request: Send a blank email to pear-dev+get-31137@lists.php.net to get a copy of this message
Hans Lellelid wrote:
Justin Patrin wrote:
If someone wants returns, they should have that option, *even in PHP5*. If you're worried about speed / parsing, PEAR_Error could be conditionally included when and if a PEAR_Error return is asked for.
I think that if PEAR decides to encourage new (php5) development using PEAR_Error, when PHP5 provides a full-featured built-in error handling system, then PEAR will simply never become an authoritative repository for PHP5 libraries. I think PEAR has an obligation to keep up with PHP development and encourage software that takes full advantage of language features.
1) In general, we're supposed to be moving to PEAR_ErrorStack instead of PEAR_Error. It's smaller, more flexible, and is a very nice system for debugging as well as error handling. 2) Developing code which deals with return values is just as valid as dealing with Exceptions. It's a different way of doing things. As many people have said, they believe that Exceptions are only for excptional circumstances and would rather use a return value.
I argue that with an appropriately designed Exception base class you can do everything needed to catch and handle errors. Warnings can be handled by trigger_error() + set_error_handler() functions or stored internally to the object.
Yes, errors can be stored internally. With PEAR_ErrorStack. Let's add a third type to my suggestion. Let's call it PEAR_ERROR_RETURN_SUCCESS. The same call is made in Package3: return $this->errorStack->push(...); With this new type, false (or NULL or 0 or something defined) will be returned. The calling code does this: if($Package3->call(...)) { //do normal stuff } else { $Package3->getError(); //or maybe $Package3->errorStack->getError(); or whatever it's supposed to be } In this case, no PEAR_Error is returned or even instantiated, the error is stored in the ErrorStack in a minimal form. This is part of why ErrorStack is a nice solution to error handling. So now we have 3 types of error handling, ALL OF WHICH COEXIST PEACEFULLY. The calling package can choose to catch an exception, get a return value, or get a returned PEAR_Error, as *it* wishes. Even if this is not implemented for PHP4, I would like the same kind of solution with Exceptions and RETURN_SUCCESS to be implemented. It will allow packages to do it the way they want to.
There are a number of solutions for warnings and notices (e.g. trigger_error, $obj->getWarnings(), or something like raiseWarning()). I'm talking about replacing PEAR_Error returns with Exceptions. Anytime a function returns a PEAR_Error it should be throwing an Exception in PHP5.
And PHP5 is just an upgraded PHP4. Just because it has Exceptions, it doesn't mean that we *have to use them*. And if we use them, it doesn't mean that we have to use them for everything. And if you want to use them, in a perfect world, it doesn't mean that *I* have to use them. A single funciton call, a single switch, and a conditional include are a very small thing to ask for for greatly increased flexibility.
Having this perfect world where every calling package can decide on the error handling system is not practical. Having every module change the application's error handling system to something it understands -- and then back again, sounds performance-poor and just crazy design.
Assuming you're using packages which use different erro handling shcemes, you have a change of the error type (one assignment), a switch to choose throw/return, and returning the error type back (one assignment).
So you would not get to choose whether or not you want to use exceptions, but that's no different from how it is now. I happen to dislike PEAR_Error, but I certainly have to use it (i.e. PEAR::isError()) in any of my classes that use a PEAR library.
Just because it was true with PEAR_Error (because centralized error handling is nice and the Error Handling features weren't built into PHP4) doesn't mean we need to lock people into an error handling scheme with PHP5.
And again, I resent that people assume I don't know what I'm talking about. I have used other OOP languages which have these features. Private and protected are *not new*. Exceptions are *not new*. I don't have to use PHP5 to understand the difference.
But why would anyone *want* to use PEAR_Error when there are exceptions? I can't understand this. Where's an example of some code that works brilliantly with return values but not with exceptions? From my perspective you can always accomplish what was possible in return-code error handling using exceptions and you can also do a *whole* lot more.
Consider the following: if($class->func()) { //do something //do more } //go on or: if(!PEAR::isError($class->func())) { //do something //do more } //go on Assuming this was an error which the caller thinks is ok, the Exception version would be: try { $class->func(); //do something //do more } catch(Exception $e) { } //go on The first two are much more readable IMHO. It's not at all obvious that the Exception being thrown relies in the $class->func() call. I suppose you could say it's the first thing, so that's what should throw the exception, but it's perfectly reaonsable for another call in the try block to throw the exception. If the coder really wants to make sure that the exception was in only the $class->func call, he would have to do something like this: try { $class->func(); try {
    //do something
    //do more
} catch(Exception $e) {
    die('there shouldn't be an exception here');
} } catch(Exception $e) { } //go on or: try { $class->func(); $ok = true; } catch(Exception $e) { $ok = false; } if($ok) { //do something //do more } //go on Neither of those is nice looking code.
I think people are telling you to try PHP5, because you haven't yet and it is very different. I think most developers that have used PHP5 see the differences as very welcome improvements -- and you are suggesting that we keep using PEAR_Error because it's what people are used to
Not because it's what people are used to. It's convenient and is an alternate method of error handling. Not everyone wants to use Exceptions for error handling because it leads to hard to read code. *You* sent this URL: http://www.andreashalter.ch/phpug/20040115/2.html Did you not read this part? "[One of] the main problems seen with exceptions [is]:
    * Overuse of Exception Handling
      Some people attempt to do all their Error Handling using Exceptions. This will end in unreadable code full of trying and catching."
This is true, as shown above. Not all errors should be Exceptions.
, or keep prefixing priv/protected w/ '_' because it's the way people are used to doing it, even if it isn't at all necessary in the new language.
It's not necessary in PHP4 either. In PHP4, it's there to give a hint to the coder that they shouldn't be touching it. In PHP5 it's for *the same thing*. This was never an argument about necessary, it's about making it easy to read/debug code.
In refleciton, I think what all these debates do illuminate is that the upgrade path to PHP5 is anything but easy. Sure you can upgrade to PHP5 but not use any PHP5 features; that will certainly make the upgrade easier, but why upgrade at all then?
1) Because it will allow you to use your PHP4 packages with little to no changes, *side by side with* PHP5 packages. As has been said by many, unless you reassign $this, PHP4 code should run fine in PHP5 (non-E_STRICT). 2) Because it allows an easy upgrade path. You start by using what you have, then rewrite to use new features *as you can*, not necessarily all at once. 3) Because it allows flexibility and ease of use.
The truth is that the ZendEngine2 is far from backwards compatible
Wait a minute. I heard that PHP4 code should run fine on PHP5 unless you try to assign $this. Do you have some evidence otherwise?
and new PHP5 code isn't going to work at all with existing PHP4 libraries.
Only if you force use of PHP5 features. Namely, throwing exceptions. Even if your PHP5 code throws exceptions, it can run in the same package with PHP4 code without a problem. The "glue" can just deal with Exceptions for the PHP5 code and errors with the PHP4 code. Or how about this. You want to use a PEAR library written for PHP4. The author isn't getting the PHP5 version done fast enough for you. That's ok because you can set the error mode to PEAR_ERROR_EXCEPTION and it will throw exceptions, just like your PHP4 code. Wow, isn't that nice? It can go the other way too.
-- not without severely crippling the PHP5 packages -- and frankly, people aren't gonna want to do that. PEAR might want that because it's easier, but PHP developers aren't going to use PHP5-only libraries that don't use PHP5 features.
If it doesn't use PHP5 features, it's not really a PHP5-only library, then is it? I don't know what your point here is. -- paperCrane <Justin Patrin>

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