Exceptions and Errors

php.internals

John Coggeshall

22 years ago
As a matter of consistency, I would like to suggest that for those extensions which have a OO/procedural syntax that the non-fatal errors generated by those extensions be thrown as Exceptions when called from an OO syntax. I have already committed such a change to Tidy, and I can't see any serious reason why such a change can't be implemented for internal classes. Feedback welcome. John
-- -=~=--=~=--=~=--=~=--=~=--=~=--=~=--=~=--=~=--=~=--=~=--=~=- John Coggeshall http://www.coggeshall.org/ The PHP Developer's Handbook http://www.php-handbook.com/ -=~=--=~=--=~=--=~=--=~=--=~=--=~=--=~=--=~=--=~=--=~=--=~=-

Adam Maccabee Trachtenberg

22 years ago
On Sun, 11 Apr 2004, John Coggeshall wrote:
> As a matter of consistency, I would like to suggest that for those > extensions which have a OO/procedural syntax that the non-fatal errors > generated by those extensions be thrown as Exceptions when called from > an OO syntax. I have already committed such a change to Tidy, and I > can't see any serious reason why such a change can't be implemented for > internal classes. > > Feedback welcome.
I wholeheartedly support this. I've been trying to document exception handling this week and it's extremely frustrating: 1) None (almost none?) of the internal classes use exceptions. This makes it difficult (if not impossible) to explain how to use exceptions because you cannot show a meaningful example. 2) Point #1 is a lie because internal classes throw exceptions when there's an error in the constructor. This is leads to wacky code: try { $db = new SQLiteDatabase('foo.db'); if ($db->query($sql)) { // fetch rows } else { // handle error } } catch { // handle exception } It's really crazy to need to mix both types of error handling within the same block of code. 3) Because internal classes don't use exceptions, I have no idea how anyone can meaningfully use exceptions in their code. Even if all userspace errors throw exceptions, people will miss lots of other errors (i.e the ones from internal classes) unless they explicitly check for them themselves and manually throw exceptions. Needing to turn errors into exceptions, however, seems to completely defeat one of the primary points of exception handling, which is separating core programming logic from error handling. I wish I had to foresight to realize this earlier, but it didn't emerge until I began to use PHP 5 in a more comprehensive way. -adam
-- adam@trachtenberg.com author of o'reilly's php cookbook avoid the holiday rush, buy your copy today!

John Coggeshall

22 years ago
On Mon, 2004-04-12 at 01:27, Adam Maccabee Trachtenberg wrote:
> 1) None (almost none?) of the internal classes use exceptions. This > makes it difficult (if not impossible) to explain how to use > exceptions because you cannot show a meaningful example.
As of today, Tidy throws Exceptions in a object context.
> It's really crazy to need to mix both types of error handling within > the same block of code.
Completely agree
-- -=~=--=~=--=~=--=~=--=~=--=~=--=~=--=~=--=~=--=~=--=~=--=~=- John Coggeshall http://www.coggeshall.org/ The PHP Developer's Handbook http://www.php-handbook.com/ -=~=--=~=--=~=--=~=--=~=--=~=--=~=--=~=--=~=--=~=--=~=--=~=-

Ferdinand Beyer

22 years ago
On 12 Apr 2004 at 12:05, Andi Gutmans wrote:
> I agree it's a problem, but as you know, for BC reasons we can't
make all
> internal functions throw exceptions. I do suggest however, that
new object
> oriented extensions throw exceptions in object context. This isn't a
BC
> break and makes sense as it's used in an object-oriented context. > In any case, I understand that throwing an exception from user-
land error
> handling works as expected so this can partially solve the problem
with
> internal functions too. > > Andi
The problem with exception thrown by a user-land error handler is to distinguish real exceptions that break the execution from informative warnings. I have just experienced this while playing around with XML Schema validation and 5.0.0b4. The current implementation always triggers two warnings telling 'Unimplemented block at xmlschemas.c:2245'. Furthermore, every validation failure is reported using PHP warnings. That's why it is impossible to use a "user-land exception thrower" with schema validation at the moment. I don't know if it is the only extension misusing the errror handling mechanism...
-- Ferdinand Beyer <fb@fbeyer.com>

Andi Gutmans

22 years ago
At 12:13 PM 4/12/2004 +0200, Ferdinand Beyer wrote:
>On 12 Apr 2004 at 12:05, Andi Gutmans wrote: > > > I agree it's a problem, but as you know, for BC reasons we can't >make all > > internal functions throw exceptions. I do suggest however, that >new object > > oriented extensions throw exceptions in object context. This isn't a >BC > > break and makes sense as it's used in an object-oriented context. > > In any case, I understand that throwing an exception from user- >land error > > handling works as expected so this can partially solve the problem >with > > internal functions too. > > > > Andi > >The problem with exception thrown by a user-land error handler is to >distinguish real exceptions that break the execution from informative >warnings. > >I have just experienced this while playing around with XML Schema >validation and 5.0.0b4. The current implementation always triggers >two warnings telling 'Unimplemented block at xmlschemas.c:2245'. >Furthermore, every validation failure is reported using PHP warnings. > >That's why it is impossible to use a "user-land exception thrower" >with schema validation at the moment. I don't know if it is the only >extension misusing the errror handling mechanism...
Yeah, I think the way things are today, there is no way of doing this well. I think that PHP should stay the way it is. If there are certain OOP extension writers who want to support exceptions I think there's no reason they shouldn't do so. It might also be possible to allow setting a flag in the constructor which tells the OOP extension if the developer wants exceptions or zend_error's. All in all, as we're not writing the language from scratch on day 1, I don't see a way to solve this problem very well. Andi

Andi Gutmans

22 years ago
At 01:41 AM 4/12/2004 -0400, John Coggeshall wrote:
>On Mon, 2004-04-12 at 01:27, Adam Maccabee Trachtenberg wrote: > > 1) None (almost none?) of the internal classes use exceptions. This > > makes it difficult (if not impossible) to explain how to use > > exceptions because you cannot show a meaningful example. > >As of today, Tidy throws Exceptions in a object context. > > > It's really crazy to need to mix both types of error handling within > > the same block of code. > >Completely agree
I agree it's a problem, but as you know, for BC reasons we can't make all internal functions throw exceptions. I do suggest however, that new object oriented extensions throw exceptions in object context. This isn't a BC break and makes sense as it's used in an object-oriented context. In any case, I understand that throwing an exception from user-land error handling works as expected so this can partially solve the problem with internal functions too. Andi

Wez Furlong

22 years ago
Note that sqlite does have an option to raise exceptions instead of errors. I haven't tried this myself; Marcus will be able to advise more on how this works. --Wez.

Marcus Börger

22 years ago
Hello Wez, SQLite only throws exceptions from constructors. This is necessary to get the "constructor failed" information. It works using the support functions from main/main.c/main/php.h: typedef enum { EH_NORMAL = 0, EH_SUPPRESS, EH_THROW } error_handling_t; PHPAPI void php_set_error_handling(error_handling_t error_handling, zend_class_entry *exception_class TSRMLS_DC); #define php_std_error_handling() php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC) php_set_error_handling(() sets the mode and class_entry. php_std_error_handling() resets the mode and class entry. EH_NORMAL => Standard behavior = no exceptions EH_SUPPRESS => Neither throw an exception nor show/log the error EH_THROW => Throw an exception if no excpetion is pending If exception_class == NULL then a standard exception will be generated. Monday, April 12, 2004, 11:31:46 PM, you wrote:
> Note that sqlite does have an option to raise exceptions instead of errors. > I haven't tried this myself; Marcus will be able to advise more on how this > works.
> --Wez.
>> try { >> $db = new SQLiteDatabase('foo.db'); >> if ($db->query($sql)) { >> // fetch rows >> } else { >> // handle error >> } >> } catch { >> // handle exception >> } >> >> It's really crazy to need to mix both types of error handling within >> the same block of code.
-- Best regards, Marcus mailto:helly@php.net

Derick Rethans

22 years ago
On Sun, 11 Apr 2004, John Coggeshall wrote:
> As a matter of consistency, I would like to suggest that for those > extensions which have a OO/procedural syntax that the non-fatal errors > generated by those extensions be thrown as Exceptions when called from > an OO syntax. I have already committed such a change to Tidy, and I > can't see any serious reason why such a change can't be implemented for > internal classes. > > Feedback welcome.
I think it's a stupid idea (actually OO is a stupid idea but that's something for another dicussion ;-): 1. In order to silently ignore failed queries you still have to put a stupid try..except block around it. 2. KISS: PHP is supposed to be SIMPLE; with all thos advanced OO stuff writing scripts for PHP starts becoming less and less easy. Sure, they are already using OO but that's just a notation. Some extensions are only OO, like DOM, but that doesn't mean that every Joe Average has any idea on what exceptions are. Please, kepe things simple. Don't force people. Derick

Andrey Hristov

22 years ago
Derick Rethans wrote:
> > > I think it's a stupid idea (actually OO is a stupid idea but that's > something for another dicussion ;-): > > 1. In order to silently ignore failed queries you still have to put a > stupid try..except block around it.
If it's used only in object context.
> > 2. KISS: PHP is supposed to be SIMPLE; with all thos advanced OO stuff > writing scripts for PHP starts becoming less and less easy. Sure, > they are already using OO but that's just a notation. Some extensions > are only OO, like DOM, but that doesn't mean that every Joe Average > has any idea on what exceptions are. Please, kepe things simple. > Don't force people. >
Supposed to be simple but oriented a little bit to the enterprise, otherwise why do we have a ext/soap? An while for the Joe Average a failed query is just nothing for an application which not fault tolerant this is something different. Joe Average even does not need to use OO interface for simple scripts, while serious application goes OO (except FUDForum ;) but Ilia wanted speeed). So, I don't find any problems of internal classes throwing exceptions in object context. This was something I though is gonna be implemented by the engine which can realize on compile time whether OO is used or not and php_error_docref() to work just like now for procedural code and throw exceptions for OO code (which can break some existing code of course). AFAIR Andi or Zeev explained that's not possible or won't be implemented. Finally, it looks that RC2 won't be released anytime soon and this issue can be fixed in the meantime. Andrey

Pierre-Alain Joye

22 years ago
On Mon, 12 Apr 2004 13:02:19 +0200 php@hristov.com (Andrey Hristov) wrote:
> Derick Rethans wrote: > > > > > > I think it's a stupid idea (actually OO is a stupid idea but > > that's something for another dicussion ;-): > > > > 1. In order to silently ignore failed queries you still have to > > put a > > stupid try..except block around it.
> If it's used only in object context.
And why OO codes should be overbloated with exceptions for non fatal errors? I do not talk about fatal userland errors but fatal php erros. But I may be a too old fashion programmer, where exceptions were used to avoid crash, ugly exit and but not control flow. I feel these exceptions issues more like the other "OO fanatic" discussions. It will fall in many annoyed things in our codes, depending about how the maintainers use exceptions. For instance (I took tidy codes, no offence for the authors, I like tidy, but not its exceptions usage): if (tidyOptIsReadOnly(opt)) { TIDY_THROW("Attempt to set read-only option '%s'", optname); return FAILURE; } Ah? Sounds more like a notice to me. This kills the KISS. My nightmare (shows the E_ERROR/E_WARNING issues explained in other posts): ./sapi/cli/php -n -r 'tidy_parse_file("foo");echo "bar";' The worst is: tidy_get_opt (internal function name) which raises an exception if the option does not exist. What a nightmare if I have to try{}catch every piece of codes because the KISS'ed value/false principle is droped in the name of OO. So yes, a little HOWTO for the usage of exceptions should be nice, both for internals and userland. But if the goals is to follow these examples, then I ask to add an ini option: use_crappy_exceptions On|Off my little 2cts on this topic, pierre

Andi Gutmans

22 years ago
At 01:02 PM 4/12/2004 +0200, Andrey Hristov wrote:
> Finally, it looks that RC2 won't be released anytime soon and this issue > can be fixed in the meantime.
Actually, I am planning on rolling RC2RC1 in the coming days. I still have a few pending engine bugs which I want to look at before I do so. As I said, OOP extension authors who prefer to throw exceptions can do so if they wish (such as ext/SOAP). I think it's important to keep the old error handling for the functional paradigm. I kind of like my idea of being able to specify exceptions or not in the constructor, but I don't think this is something which should be mandatory. Andi

Andi Gutmans

22 years ago
At 01:02 PM 4/12/2004 +0200, Andrey Hristov wrote:
> Finally, it looks that RC2 won't be released anytime soon and this issue > can be fixed in the meantime.
BTW, the reason why I think RC2 should be released ASAP is because of the fix in compatibility_mode and the studlyCaps changes. Both of these changes should be released as quickly as possible. Andi

Andi Gutmans

22 years ago
At 12:41 PM 4/12/2004 +0200, Derick Rethans wrote:
>On Sun, 11 Apr 2004, John Coggeshall wrote: > > > As a matter of consistency, I would like to suggest that for those > > extensions which have a OO/procedural syntax that the non-fatal errors > > generated by those extensions be thrown as Exceptions when called from > > an OO syntax. I have already committed such a change to Tidy, and I > > can't see any serious reason why such a change can't be implemented for > > internal classes. > > > > Feedback welcome. > >I think it's a stupid idea (actually OO is a stupid idea but that's >something for another dicussion ;-): > >1. In order to silently ignore failed queries you still have to put a > stupid try..except block around it. > >2. KISS: PHP is supposed to be SIMPLE; with all thos advanced OO stuff > writing scripts for PHP starts becoming less and less easy. Sure, > they are already using OO but that's just a notation. Some extensions > are only OO, like DOM, but that doesn't mean that every Joe Average > has any idea on what exceptions are. Please, kepe things simple. > Don't force people.
Derick, The fact that you have something personal against OOP doesn't mean it's not good. I think that functional context should continue to work as usual, but there's a big advantage to be able to catch problems with try/catch and not have to if() each internal function call separately (which you probably don't do :) I don't see a problem with OOP extensions throwing exceptions. Andi

Ilia A.

22 years ago
On April 12, 2004 06:45 am, Andi Gutmans wrote:
> I don't see a problem with OOP extensions throwing exceptions. > Andi
There is 1 problem with this approach. Currently an uncaught exceptions results in a fatal error (E_ERROR) meaning that if a particular method throws an exceptions it MUST be caught otherwise the script will terminate. Having to wrap some methods inside exceptions can be extremely frustrating since you may want to allow those methods to fail. For example the query method in SQLite can safely be allowed to fail in certain instances. In other instances when you care about failures there may be a need to implement custom handlers depending on the nature of the error. For example if a query fails due to a uniqness constrait, an UPDATE query would be ran while in all other instances an error would be logged etc... Ilia

Adam Maccabee Trachtenberg

22 years ago
On Mon, 12 Apr 2004, Ilia Alshanetsky wrote:
> There is 1 problem with this approach. Currently an uncaught exceptions > results in a fatal error (E_ERROR) meaning that if a particular method throws > an exceptions it MUST be caught otherwise the script will terminate. Having > to wrap some methods inside exceptions can be extremely frustrating since you > may want to allow those methods to fail.
Yes. This sucks. Maybe PHP should only issue exceptions for problems of E_WARNING severity. An exception is an "Exceptional Event." If you have an E_NOTICE or E_STRICT then that's an informational event, not a exceptional one. Either that or uncaught exceptions should be E_WARNINGs instead of E_ERRORs. (I don't want to introduce Java's checked versus unchecked exception concept.)
> For example the query method in SQLite can safely be allowed to fail > in certain instances. In other instances when you care about > failures there may be a need to implement custom handlers depending > on the nature of the error. For example if a query fails due to a > uniqness constrait, an UPDATE query would be ran while in all other > instances an error would be logged etc...
Still, you shouldn't be ignoring E_WARNINGs unless you have a good reason. Your code cannot correctly retrieve those rows from the database when you've ignored the error telling you that there was a problem connecting to the database. :) Handling UNIQUEness queries is exactly the type of problem you're going to need to trap. For example: try { $db = new SQLiteDatabase('foo.db'); $db->query('INSERT...'); } catch (SQLiteException $e) { if ($e->getCode() == 19) { // UNIQUEness violation $db->query('UPDATE...'); } else { // log error error_log($e->getMessage() . ': ' . $e->getCode()); } } -adam
-- adam@trachtenberg.com author of o'reilly's php cookbook avoid the holiday rush, buy your copy today!

George Schlossnagle

22 years ago
On Apr 12, 2004, at 10:58 AM, Adam Maccabee Trachtenberg wrote:
> On Mon, 12 Apr 2004, Ilia Alshanetsky wrote: > >> There is 1 problem with this approach. Currently an uncaught >> exceptions >> results in a fatal error (E_ERROR) meaning that if a particular >> method throws >> an exceptions it MUST be caught otherwise the script will terminate. >> Having >> to wrap some methods inside exceptions can be extremely frustrating >> since you >> may want to allow those methods to fail. > > Yes. This sucks. Maybe PHP should only issue exceptions for problems > of E_WARNING severity. An exception is an "Exceptional Event." If you > have an E_NOTICE or E_STRICT then that's an informational event, not a > exceptional one.
I'm fine with this, but it's really just a documentation problem, right? Your method can still fail, you just need to try/catch around it. try { $obj->bornToFail(); } catch(Exception $e){} Uglier than just swallowing a warning for sure, but still just a doc problem.
> Either that or uncaught exceptions should be E_WARNINGs instead of > E_ERRORs. (I don't want to introduce Java's checked versus unchecked > exception concept.)
-1. George

Michael Walter

22 years ago
> > On Apr 12, 2004, at 10:58 AM, Adam Maccabee Trachtenberg wrote: > >> On Mon, 12 Apr 2004, Ilia Alshanetsky wrote: >> >>> There is 1 problem with this approach. Currently an uncaught >>> exceptions >>> results in a fatal error (E_ERROR) meaning that if a particular >>> method throws >>> an exceptions it MUST be caught otherwise the script will terminate. >>> Having >>> to wrap some methods inside exceptions can be extremely frustrating >>> since you >>> may want to allow those methods to fail. >> >> Yes. This sucks. Maybe PHP should only issue exceptions for problems >> of E_WARNING severity. An exception is an "Exceptional Event." If you >> have an E_NOTICE or E_STRICT then that's an informational event, not a >> exceptional one. > > I'm fine with this, but it's really just a documentation problem, > right? Your method can still fail, you just need to try/catch around > it. > > try { > $obj->bornToFail(); > } > catch(Exception $e){} > > Uglier than just swallowing a warning for sure, but still just a doc > problem.
Might there be a possibility that an exception inside a "@ context" could be ignored, too (that might also work with active custom error handlers, I guess)? Cheers, Michael

Ilia A.

22 years ago
On April 12, 2004 10:58 am, Adam Maccabee Trachtenberg wrote:
> Still, you shouldn't be ignoring E_WARNINGs unless you have a good > reason.
There are plenty of situations where E_WARNING can be safely ignored. And even more situations where E_NOTICE/E_STRICT can be ignored.
> Your code cannot correctly retrieve those rows from the > database when you've ignored the error telling you that there was a > problem connecting to the database. :)
You may not want to retrieve the rows in the 1st place.
> Handling UNIQUEness queries is exactly the type of problem you're > going to need to trap. For example:
Your example is not entirely correct. You'd first need to use $db->lastError() to the error code, $e->getCode() will return something else all together. However the bottom line is that now your exception handling mechanism is far more complex then it should/could be. If your block has a query() method with a query that can fail you'd need to add special conditions to handle it in the end you end up with an overly complex handling mechanism. If you start putting an try {} catch {} block around every individual query method as an alternative, then you kill the whole point of exceptions, no? Ilia

Adam Maccabee Trachtenberg

22 years ago
On Mon, 12 Apr 2004, Ilia Alshanetsky wrote:
> On April 12, 2004 10:58 am, Adam Maccabee Trachtenberg wrote: > > Still, you shouldn't be ignoring E_WARNINGs unless you have a good > > reason. > > There are plenty of situations where E_WARNING can be safely ignored. And even > more situations where E_NOTICE/E_STRICT can be ignored.
Well, like I said, I'm against exceptions on E_NOTICE/E_STRICT. I think there's some agreement on this point. Well, you, me, George, and Derick. I add Derick because he's always against exceptions. :) As to E_WARNINGs, what to do? Sometimes they can be safely ignored, but it takes an experienced programmer to know those cases.
> > Your code cannot correctly retrieve those rows from the > > database when you've ignored the error telling you that there was a > > problem connecting to the database. :) > > You may not want to retrieve the rows in the 1st place.
So you're saying you write code like: // Don't care if this prints anything: $db = new SQLiteDatabase('foo.db'); $r = $db->query($sql); foreach ($r as $row) { processRow($row); } I think only two sets of programmers do this. Unfortunately, they're at the spectrums. Newbies and gurus. Newbies because they don't know any better and gurus because they know exactly what's going to happen. I'm trying to get newbies to move into the middle range and I'm ignoring the top 1% of developers. :)
> > Handling UNIQUEness queries is exactly the type of problem you're > > going to need to trap. For example: > > Your example is not entirely correct. You'd first need to use > $db->lastError() to the error code, $e->getCode() will return something else > all together. However the bottom line is that now your exception handling > mechanism is far more complex then it should/could be. If your block has a > query() method with a query that can fail you'd need to add special > conditions to handle it in the end you end up with an overly complex handling > mechanism.
Right. Sorry about that. I had played around with trying to get SQLite to throw exceptions and had placed the lastError() as the exception code.
> If you start putting an try {} catch {} block around every individual query > method as an alternative, then you kill the whole point of exceptions, no?
FWIW, I just checked, and Java handles this dilemma in JDBC by *not* throwing exceptions upon SQL warnings. They still throw SQLExceptions for major DB errors. I am willing to concede that SQL parse errors aren't the best example here, but that doesn't mean extensions should never throw exceptions. -adam
-- adam@trachtenberg.com author of o'reilly's php cookbook avoid the holiday rush, buy your copy today!

Ilia A.

22 years ago
On April 12, 2004 11:42 am, Adam Maccabee Trachtenberg wrote:
> As to E_WARNINGs, what to do? Sometimes they can be safely ignored, > but it takes an experienced programmer to know those cases.
Perhaps, but if you limit the experienced programmer's options and/or make using more advanced capabilities of the language more difficult you will lose those programmers to other languages. Consequently these programmers are usually the ones responsible for large deployments of the language.
> So you're saying you write code like: > > // Don't care if this prints anything: > $db = new SQLiteDatabase('foo.db'); > $r = $db->query($sql); > foreach ($r as $row) { > processRow($row); > }
Almost ;-) $r = $db->query($sql) or sql_error_handler($sql, $db); It'll be the job of sql_error_handler() to determine what type of an error had occurred and what action to take if any.
> FWIW, I just checked, and Java handles this dilemma in JDBC by *not* > throwing exceptions upon SQL warnings. They still throw SQLExceptions > for major DB errors.
Well, that would mean that you'll never be certain what may throw an exceptions giving you a nasty mix of both that will confuse experienced and inexperienced developers alike. Ilia

Greg Beaver

22 years ago
Adam Maccabee Trachtenberg wrote:
> I am willing to concede that SQL parse errors aren't the best example > here, but that doesn't mean extensions should never throw exceptions.
If a user has written code expecting it to work in PHP 4 and PHP 5 with a registered error handler, it has to be completely rewritten. Exceptions, by nature, can not be caught at the global level and then modified, they are local. Of course, you could just surround your global code with a try {} catch {} but that is just about the worst hack I can imagine. Unless there is a way to "resume" execution after the point of the error (i.e. exactly how the current error handling works), exceptions will only make things more exasperating. If I have to surround every single method call with try {} catch {}, that = a bad design decision. - say byebye to readability - what if an extension upgrades and throws a new, more specific kind of exception? instant code breakage, unless the catch-all is not paranoid - EVERY try {} catch {} will need a catch-all, unless you're willing to risk total breakage later. - error handling is suddenly forced to be directly integrated with program logic, and isn't that the opposite of exception handling's goals? Greg P.S. This is what I mean by a "resume" statement: function blah() { $a = $someobject->throwsexception(); $nextstatement = 'works?'; } ... try { blah(); } catch (Exception $e) { log_exception($e); if (thingsareok()) { resume; // execution starts at "$nextstatement = 'works?';" } } Without the ability to resume, we are forced to do function blah() { try { $a = $someobject->throwsexception(); } catch (Exception $e) { $ok = pass_to_global_exception_handler_and_logger($e); if (!$ok) { throw ($e); } } $nextstatement = 'ack'; } for even the most minor of error conditions

Adam Maccabee Trachtenberg

22 years ago
On Mon, 12 Apr 2004, Greg Beaver wrote:
> Adam Maccabee Trachtenberg wrote: > > > I am willing to concede that SQL parse errors aren't the best example > > here, but that doesn't mean extensions should never throw exceptions. > > If a user has written code expecting it to work in PHP 4 and PHP 5 with > a registered error handler, it has to be completely rewritten.
If you're expecting this code to work in both PHP 4 and PHP 5, you're not using the OO extension interface, so no exceptions will be thrown. Things will work just like before. I also presume that exceptions are not handled by a registed error handler. That would be madness. :) I think by now I am resigned to the situation that PHP's internal error reporting system doesn't doesn't map well to exception handling. This problem is at least somewhat related to inconsistent application of E_WARNINGs, E_ERRORs, etc. Certain extensions (SOAP, Ming) love to throw E_ERRORs. Others won't throw an E_ERROR in even the worst of circumstances. Therefore, sometimes E_WARNINGs are harmless and other times they're fatal. Oh well. -adam
-- adam@trachtenberg.com author of o'reilly's php cookbook avoid the holiday rush, buy your copy today!

Adam Maccabee Trachtenberg

22 years ago
On Mon, 12 Apr 2004, Andi Gutmans wrote:
> I think that functional context should continue to work as usual, but > there's a big advantage to be able to catch problems with try/catch and not > have to if() each internal function call separately (which you probably > don't do :) > I don't see a problem with OOP extensions throwing exceptions.
I agree. I don't think we should modify the functional context at all. However, uf bundled extensions don't throw exceptions (or even worse, some do and some don't) then why did we both implementing exceptions? How can anyone rationally design an application when half of their problems issue errors and the other half throw exceptions? That's a recipe for disaster. -adam
-- adam@trachtenberg.com author of o'reilly's php cookbook avoid the holiday rush, buy your copy today!

Derick Rethans

22 years ago
On Mon, 12 Apr 2004, Adam Maccabee Trachtenberg wrote:
> How can anyone rationally design an application when half of their > problems issue errors and the other half throw exceptions? That's a > recipe for disaster.
Exactly the reason why nothing should throw exceptions at all. Derick

Adam Maccabee Trachtenberg

22 years ago
On Mon, 12 Apr 2004, Derick Rethans wrote:
> On Mon, 12 Apr 2004, Adam Maccabee Trachtenberg wrote: > > > How can anyone rationally design an application when half of their > > problems issue errors and the other half throw exceptions? That's a > > recipe for disaster. > > Exactly the reason why nothing should throw exceptions at all.
If nothing should throw exceptions then they shouldn't be in the language. However, having decided to place exceptions to the language, it's only rational to implement them in a sane way. I understand you're against them. Personally, I may not use them. However, I really don't think it makes any sense to set exceptions up for failure with a half-baked implementation. (I'm not saying the ZE2 part of exeptions is half-baked. That works. It's the deployment of exceptions that's half-baked.) -adam
-- adam@trachtenberg.com author of o'reilly's php cookbook avoid the holiday rush, buy your copy today!

Sterling Hughes

22 years ago
On Apr 12, 2004, at 3:45 AM, Andi Gutmans wrote:
> At 12:41 PM 4/12/2004 +0200, Derick Rethans wrote: >> On Sun, 11 Apr 2004, John Coggeshall wrote: >> >> > As a matter of consistency, I would like to suggest that for those >> > extensions which have a OO/procedural syntax that the non-fatal >> errors >> > generated by those extensions be thrown as Exceptions when called >> from >> > an OO syntax. I have already committed such a change to Tidy, and I >> > can't see any serious reason why such a change can't be implemented >> for >> > internal classes. >> > >> > Feedback welcome. >> >> I think it's a stupid idea (actually OO is a stupid idea but that's >> something for another dicussion ;-): >> >> 1. In order to silently ignore failed queries you still have to put a >> stupid try..except block around it. >> >> 2. KISS: PHP is supposed to be SIMPLE; with all thos advanced OO stuff >> writing scripts for PHP starts becoming less and less easy. Sure, >> they are already using OO but that's just a notation. Some >> extensions >> are only OO, like DOM, but that doesn't mean that every Joe Average >> has any idea on what exceptions are. Please, kepe things simple. >> Don't force people. > > Derick, > > The fact that you have something personal against OOP doesn't mean > it's not good. > I think that functional context should continue to work as usual, but > there's a big advantage to be able to catch problems with try/catch > and not have to if() each internal function call separately (which you > probably don't do :) > I don't see a problem with OOP extensions throwing exceptions. >
I like OO (*), and I think warnings (non-fatal errors) as exceptions are a stupid idea. Does that count? ;-) Exceptions in languages like Java are used explicitly to catch fatal errors, not to catch basic errors. Converting warnings to exceptions would change the meaning of a warning from something which is nice for development, or logging purposes, but handled by your control flow, into an unrecoverable error. Errors as exceptions are a different story. I don't think that's a bad idea at all. But leave good alone, warnings shouldn't be exceptions. -Sterling (*) Though my like is most definitely due to stockholm syndrome, and excessive brainrape. Nonetheless. :)

George Schlossnagle

22 years ago
On Apr 12, 2004, at 11:42 AM, Sterling Hughes wrote:
> > I like OO (*), and I think warnings (non-fatal errors) as exceptions > are a stupid idea. Does that count? ;-) > > Exceptions in languages like Java are used explicitly to catch fatal > errors, not to catch basic errors.
If 'languages like Java' means languages designed for OO, then this is not true. Python throws exceptions for almost everything (KeyError, for example). Even Java throws exceptions (java.sql.Exception) for things like failed database connections which are warnings in PHP. George

Sterling Hughes

22 years ago
On Apr 12, 2004, at 8:50 AM, George Schlossnagle wrote:
> > On Apr 12, 2004, at 11:42 AM, Sterling Hughes wrote: >> >> I like OO (*), and I think warnings (non-fatal errors) as exceptions >> are a stupid idea. Does that count? ;-) >> >> Exceptions in languages like Java are used explicitly to catch fatal >> errors, not to catch basic errors. > > If 'languages like Java' means languages designed for OO, then this is > not true. Python throws exceptions for almost everything (KeyError, > for example). Even Java throws exceptions (java.sql.Exception) for > things like failed database connections which are warnings in PHP. >
Languages like Java doesn't mean languages designed for OO, but languages closely adhering to the OO model that PHP uses, Java being the language that can most easily be called the parent of our current model - although I do keep Python in this context even after your KeyError example. The triviality of an exception doesn't make exceptions themselves less severe. Whether or not a KeyError is warranted as an E_ERROR, doesn't in fact change that a KeyError will bump you firmly out of your control flow branch, and make you handle an error condition. In PHP, E_WARNINGs may be misused (that's a discussion for another time, i think); but the fact remains, they do not end your current control flow branch. Changing E_WARNING's to errors catchable by try{}catch{} will not only break BC, but will not make sense for a large number of warnings currently thrown for PHP and lead to the same inconsistencies. John has gone ahead and committed a perfect example of where exceptions just mess things up. In the tidy extension if you try and set an unknown configuration option it throws an exception. This is not by any stretch of the imagination an unrecoverable error, but rather a simple failure. Yet, if you use tidy in a script, and it is not within a try {} catch {} block your script execution will be terminated because the configuration option could not be resolved. This is much less than desirable and probably confusing for someone who doesn't understand what an exception or why he should care. You might argue that python or java would throw an exception in this case. For the majority of the java standard library and python code i have found this the opposite, however, even conceding that, PHP should never do this. We have the concept of warnings, in our world an error of this type does *not* terminate script execution. There are even less severe usages of warnings throughout the PHP source code, and there is no reason to convert them to exceptions. And if you don't, you still have the same inconsistencies. Java and Python both use a mix of philosophies, and indeed there is no complete consensus. However, in my experience and the books that I've read on the subject, the general thought is: a) throw specific exceptions, not just a "tidy_exception." PHP would need to add a library of built-in exceptions to make this even remotely useful. this is not feasible to do at RC1.66666667 b) don't throw exceptions except when truly exceptional. a function failing is usually not an exception, but rather signified by failure. The exception to this is when using constructors that contain logic (considered bad practice by many btw), and overloading. In these cases exceptions are used in leu of a better solution. This brings us back to KeyError - KeyError is only thrown when overloading is used: names = ["barney", "fred", "wilma"] print names["betty"] # throws an exception print names.get("betty") # returns None Most of the exceptions i've found when using both these languages happen on something that maps to something more severe than a configuration option not being found. YMMV. -Sterling

John Coggeshall

22 years ago
On Mon, 2004-04-12 at 13:00, Sterling Hughes wrote:
> not end your current control flow branch. Changing E_WARNING's to > errors catchable by try{}catch{} will not only break BC, but will not > make sense for a large number of warnings currently thrown for PHP and > lead to the same inconsistencies.
There is no BC break here. We are talking about specifically new extensions written against ZE2 which have error conditions that should be recoverable -- and *only* in the object context. Since most of PHP does not provide a object context, there is no expectation that they should be modified for exceptions.
> John has gone ahead and committed a perfect example of where exceptions > just mess things up. In the tidy extension if you try and set an > unknown configuration option it throws an exception. This is not by > any stretch of the imagination an unrecoverable error, but rather a > simple failure. Yet, if you use tidy in a script, and it is not within > a try {} catch {} block your script execution will be terminated > because the configuration option could not be resolved. This is much > less than desirable and probably confusing for someone who doesn't > understand what an exception or why he should care.
You have pulled one edge case out of an entire API, and the problem here is probably that you shouldn't complain about setting an invalid configuration option at all -- perhaps as a E_NOTICE. Furthermore, this exception will only occur if you use $a = new tidy() instead of $a = tidy_parse_file().
> You might argue that python or java would throw an exception in this > case. For the majority of the java standard library and python code i > have found this the opposite, however, even conceding that, PHP should > never do this. We have the concept of warnings, in our world an error > of this type does *not* terminate script execution. There are even > less severe usages of warnings throughout the PHP source code, and > there is no reason to convert them to exceptions. And if you don't, > you still have the same inconsistencies.
Again, we are talking about a very specific situation (PHP 5 extensions written using a dual-syntax model).Things in the PHP 4 branch are not an issue here, there is no expectation that such things would be changed.
> a) throw specific exceptions, not just a "tidy_exception." PHP would > need to add a library of built-in exceptions to make this even remotely > useful. this is not feasible to do at RC1.66666667
Agreed. You can't do this in the time allowed. However, you can make things throw tidy_exception and then in PHP 5.1 throw tidySomeOtherMoreSpecificException which extends tidy_exception.
> b) don't throw exceptions except when truly exceptional. a function > failing is usually not an exception, but rather signified by failure. > The exception to this is when using constructors that contain logic > (considered bad practice by many btw), and overloading. In these cases > exceptions are used in leu of a better solution. This brings us back > to KeyError - KeyError is only thrown when overloading is used:
If you're argument is that there should be some sort of consistency on when an error is really an exception, I can't agree more.. However, that it itself is an admission that there is a place for Exceptions in internal PHP 5 OO which is not being addressed.
> Most of the exceptions i've found when using both these languages > happen on something that maps to something more severe than a > configuration option not being found. YMMV.
Its a two-line change that I'm willing to make -- I'm more concerned about the other extensions which are not using exceptions at all, especially when they are warranted. John
-- -=~=--=~=--=~=--=~=--=~=--=~=--=~=--=~=--=~=--=~=--=~=--=~=- John Coggeshall http://www.coggeshall.org/ The PHP Developer's Handbook http://www.php-handbook.com/ -=~=--=~=--=~=--=~=--=~=--=~=--=~=--=~=--=~=--=~=--=~=--=~=-

Pierre-Alain Joye

22 years ago
On Mon, 12 Apr 2004 13:18:51 -0400 john@coggeshall.org (John Coggeshall) wrote: <snip>
> Again, we are talking about a very specific situation (PHP 5 > extensions written using a dual-syntax model).Things in the PHP 4 > branch are not an issue here, there is no expectation that such > things would be changed.
We may keep in mind that a specific (or rare) situations now will certainly be a not so rare situation in a near future. When PHP5 is out and people start to create php5 only extensions (thinking that the internal API will then really be freezed). pierre

George Schlossnagle

22 years ago
On Apr 12, 2004, at 1:21 PM, Pierre-Alain Joye wrote:
> On Mon, 12 Apr 2004 13:18:51 -0400 > john@coggeshall.org (John Coggeshall) wrote: > > <snip> >> Again, we are talking about a very specific situation (PHP 5 >> extensions written using a dual-syntax model).Things in the PHP 4 >> branch are not an issue here, there is no expectation that such >> things would be changed. > > We may keep in mind that a specific (or rare) situations now will > certainly be a not so rare situation in a near future. When PHP5 is > out and people start to create php5 only extensions (thinking that > the internal API will then really be freezed).
That's why this discussion is happening now. George

George Schlossnagle

22 years ago
On Apr 12, 2004, at 1:00 PM, Sterling Hughes wrote:
> > On Apr 12, 2004, at 8:50 AM, George Schlossnagle wrote: > >> >> On Apr 12, 2004, at 11:42 AM, Sterling Hughes wrote: >>> >>> I like OO (*), and I think warnings (non-fatal errors) as exceptions >>> are a stupid idea. Does that count? ;-) >>> >>> Exceptions in languages like Java are used explicitly to catch fatal >>> errors, not to catch basic errors. >> >> If 'languages like Java' means languages designed for OO, then this >> is not true. Python throws exceptions for almost everything >> (KeyError, for example). Even Java throws exceptions >> (java.sql.Exception) for things like failed database connections >> which are warnings in PHP. >> > > Languages like Java doesn't mean languages designed for OO, but > languages closely adhering to the OO model that PHP uses, Java being > the language that can most easily be called the parent of our current > model - although I do keep Python in this context even after your > KeyError example. The triviality of an exception doesn't make > exceptions themselves less severe. Whether or not a KeyError is > warranted as an E_ERROR, doesn't in fact change that a KeyError will > bump you firmly out of your control flow branch, and make you handle > an error condition. In PHP, E_WARNINGs may be misused (that's a > discussion for another time, i think); but the fact remains, they do > not end your current control flow branch. Changing E_WARNING's to > errors catchable by try{}catch{} will not only break BC, but will not > make sense for a large number of warnings currently thrown for PHP and > lead to the same inconsistencies.
A KeyError is an E_NOTICE in PHP. It's so frequent in loosely typed languages that it is rarely severe. Your argument is a tautology: the only reason it breaks control-flow in Python is because it's defined to break control-flow there by means of it being an exception.
> John has gone ahead and committed a perfect example of where > exceptions just mess things up. In the tidy extension if you try and > set an unknown configuration option it throws an exception. This is > not by any stretch of the imagination an unrecoverable error, but > rather a simple failure. Yet, if you use tidy in a script, and it is > not within a try {} catch {} block your script execution will be > terminated because the configuration option could not be resolved. > This is much less than desirable and probably confusing for someone > who doesn't understand what an exception or why he should care.
I don't have a strong feeling about this either way, but to play devils advocate: You requested an option be set. That option could not be set because it is impossible to set a non-existent option. How do you know how someone wants to handle that error?
> You might argue that python or java would throw an exception in this > case. For the majority of the java standard library and python code i > have found this the opposite, however, even conceding that, PHP should > never do this. We have the concept of warnings, in our world an error > of this type does *not* terminate script execution. There are even > less severe usages of warnings throughout the PHP source code, and > there is no reason to convert them to exceptions. And if you don't, > you still have the same inconsistencies.
The discussion was on OO code throwing exceptions. Given that there is very little OO core code in php4, I don't see a widespread conversion happening.
> > Java and Python both use a mix of philosophies, and indeed there is no > complete consensus. However, in my experience and the books that I've > read on the subject, the general thought is: > > a) throw specific exceptions, not just a "tidy_exception." PHP would > need to add a library of built-in exceptions to make this even > remotely useful. this is not feasible to do at RC1.66666667
But the beauty of OO Code is that all the tidy exceptions should derive from TidyException. So life can continue as before, with no BC break.
> > b) don't throw exceptions except when truly exceptional. a function > failing is usually not an exception, but rather signified by failure. > The exception to this is when using constructors that contain logic > (considered bad practice by many btw), and overloading. In these > cases exceptions are used in leu of a better solution. This brings us > back to KeyError - KeyError is only thrown when overloading is used: > > names = ["barney", "fred", "wilma"] > print names["betty"] # throws an exception > print names.get("betty") # returns None
You'll have a hard time defending Python as being restrained in it's use of exceptions for warnings. It's a rather exception-happy langugae and throws exceptions for the equivalent of most PHP E_NOTICEs.
> Most of the exceptions i've found when using both these languages > happen on something that maps to something more severe than a > configuration option not being found. YMMV.
The key point that you're missing in all this is that _you_ don't know what's a serious error and what's not. Only the developer knows. For instance, the python smtplib can throw any number of exceptions based on bad connect data or bad command responses. Is this a 'serious' error? It depends. If sending a mail is an inconsequential part of the app, maybe it's just an informational warning. It's also easy to imagine it being a very critical, non-recoverable error. The severity of the error lies entirely in the purview of the receiver. Nothing sums this up for me better than KeyError, which is almost never fatal in my applications but which constantly bites me in the ass. Obviously your experiences may differ, which is really the whole point. George

Sterling Hughes

22 years ago
> >> John has gone ahead and committed a perfect example of where >> exceptions just mess things up. In the tidy extension if you try and >> set an unknown configuration option it throws an exception. This is >> not by any stretch of the imagination an unrecoverable error, but >> rather a simple failure. Yet, if you use tidy in a script, and it is >> not within a try {} catch {} block your script execution will be >> terminated because the configuration option could not be resolved. >> This is much less than desirable and probably confusing for someone >> who doesn't understand what an exception or why he should care. > > I don't have a strong feeling about this either way, but to play > devils advocate: You requested an option be set. That option could > not be set because it is impossible to set a non-existent option. How > do you know how someone wants to handle that error? >
I assume they don't want their script to stop executing, their transactions to be rolled back and a nasty error page shown : "Uncaught exception, could not set tabsize to 2 spaces" That could just be my crazy assumption though.
>> You might argue that python or java would throw an exception in this >> case. For the majority of the java standard library and python code >> i have found this the opposite, however, even conceding that, PHP >> should never do this. We have the concept of warnings, in our world >> an error of this type does *not* terminate script execution. There >> are even less severe usages of warnings throughout the PHP source >> code, and there is no reason to convert them to exceptions. And if >> you don't, you still have the same inconsistencies. > > The discussion was on OO code throwing exceptions. Given that there > is very little OO core code in php4, I don't see a widespread > conversion happening. >
No, this discussion was on having exceptions thrown instead of E_WARNINGs inside OO code. I'm pointing out that the two paradigms don't map, and in other languages for many of the common errors given by E_WARNINGs (but not all) simply wouldn't propagate as Exceptions. Many cases it would, but in order for this idea to work, it needs to map for the most part, which it doesn't.
>> >> Java and Python both use a mix of philosophies, and indeed there is >> no complete consensus. However, in my experience and the books that >> I've read on the subject, the general thought is: >> >> a) throw specific exceptions, not just a "tidy_exception." PHP would >> need to add a library of built-in exceptions to make this even >> remotely useful. this is not feasible to do at RC1.66666667 > > But the beauty of OO Code is that all the tidy exceptions should > derive from TidyException. So life can continue as before, with no BC > break. > >> >> b) don't throw exceptions except when truly exceptional. a function >> failing is usually not an exception, but rather signified by failure. >> The exception to this is when using constructors that contain logic >> (considered bad practice by many btw), and overloading. In these >> cases exceptions are used in leu of a better solution. This brings >> us back to KeyError - KeyError is only thrown when overloading is >> used: >> >> names = ["barney", "fred", "wilma"] >> print names["betty"] # throws an exception >> print names.get("betty") # returns None > > You'll have a hard time defending Python as being restrained in it's > use of exceptions for warnings. It's a rather exception-happy > langugae and throws exceptions for the equivalent of most PHP > E_NOTICEs. >
I haven't noticed that, and I've written quite a bit python code. It does throw exceptions, no argument, but it depends largely on what you are doing. The above example you've given is a place where an exception is not out of place (although I don't particularly like one being thrown), because you are using an overload. Different paradigm than PHP arrays imho.
>> Most of the exceptions i've found when using both these languages >> happen on something that maps to something more severe than a >> configuration option not being found. YMMV. > > The key point that you're missing in all this is that _you_ don't know > what's a serious error and what's not. Only the developer knows. For > instance, the python smtplib can throw any number of exceptions based > on bad connect data or bad command responses. Is this a 'serious' > error? It depends. If sending a mail is an inconsequential part of > the app, maybe it's just an informational warning. It's also easy to > imagine it being a very critical, non-recoverable error. The severity > of the error lies entirely in the purview of the receiver. > > Nothing sums this up for me better than KeyError, which is almost > never fatal in my applications but which constantly bites me in the > ass. Obviously your experiences may differ, which is really the whole > point. >
Well, you can use get() now and be happy. :) I'm not saying that exceptions should never be used. But, John suggested "As a matter of consistency, I would like to suggest that for those extensions which have a OO/procedural syntax that the non-fatal errors generated by those extensions be thrown as Exceptions when called from an OO syntax." Either i'm missing the point or we are agreeing this shouldn't be so. -Sterling

George Schlossnagle

22 years ago
On Apr 12, 2004, at 2:14 PM, Sterling Hughes wrote:
> >> >>> John has gone ahead and committed a perfect example of where >>> exceptions just mess things up. In the tidy extension if you try >>> and set an unknown configuration option it throws an exception. >>> This is not by any stretch of the imagination an unrecoverable >>> error, but rather a simple failure. Yet, if you use tidy in a >>> script, and it is not within a try {} catch {} block your script >>> execution will be terminated because the configuration option could >>> not be resolved. This is much less than desirable and probably >>> confusing for someone who doesn't understand what an exception or >>> why he should care. >> >> I don't have a strong feeling about this either way, but to play >> devils advocate: You requested an option be set. That option could >> not be set because it is impossible to set a non-existent option. >> How do you know how someone wants to handle that error? >> > > I assume they don't want their script to stop executing, their > transactions to be rolled back and a nasty error page shown : > > "Uncaught exception, could not set tabsize to 2 spaces" > > That could just be my crazy assumption though.
It is. It's a hardocded portion of their app, and they made a mistake. They may not care, but it's also possible that they do. Assuming that they don't care enough to fix it seems equally crazy to me.
>>> You might argue that python or java would throw an exception in this >>> case. For the majority of the java standard library and python code >>> i have found this the opposite, however, even conceding that, PHP >>> should never do this. We have the concept of warnings, in our world >>> an error of this type does *not* terminate script execution. There >>> are even less severe usages of warnings throughout the PHP source >>> code, and there is no reason to convert them to exceptions. And if >>> you don't, you still have the same inconsistencies. >> >> The discussion was on OO code throwing exceptions. Given that there >> is very little OO core code in php4, I don't see a widespread >> conversion happening. >> > > No, this discussion was on having exceptions thrown instead of > E_WARNINGs inside OO code.
Rewind to the beginning of the discussion, the scope is not as broad as you claim.
> I'm pointing out that the two paradigms don't map, and in other > languages for many of the common errors given by E_WARNINGs (but not > all) simply wouldn't propagate as Exceptions. Many cases it would, > but in order for this idea to work, it needs to map for the most part, > which it doesn't.
[snip]
>> You'll have a hard time defending Python as being restrained in it's >> use of exceptions for warnings. It's a rather exception-happy >> langugae and throws exceptions for the equivalent of most PHP >> E_NOTICEs. >> > > I haven't noticed that, and I've written quite a bit python code. It > does throw exceptions, no argument, but it depends largely on what you > are doing. The above example you've given is a place where an > exception is not out of place (although I don't particularly like one > being thrown), because you are using an overload. Different paradigm > than PHP arrays imho. > >>> Most of the exceptions i've found when using both these languages >>> happen on something that maps to something more severe than a >>> configuration option not being found. YMMV. >> >> The key point that you're missing in all this is that _you_ don't >> know what's a serious error and what's not. Only the developer >> knows. For instance, the python smtplib can throw any number of >> exceptions based on bad connect data or bad command responses. Is >> this a 'serious' error? It depends. If sending a mail is an >> inconsequential part of the app, maybe it's just an informational >> warning. It's also easy to imagine it being a very critical, >> non-recoverable error. The severity of the error lies entirely in >> the purview of the receiver. >> >> Nothing sums this up for me better than KeyError, which is almost >> never fatal in my applications but which constantly bites me in the >> ass. Obviously your experiences may differ, which is really the >> whole point. >> > > Well, you can use get() now and be happy. :)
I could, I could also catch my exceptions. There are plenty of other exceptions (casting errors, etc) that will irk me whenever I use Python.
> > I'm not saying that exceptions should never be used. But, John > suggested "As a matter of consistency, I would like to suggest that > for those extensions which have a OO/procedural syntax that the > non-fatal errors > generated by those extensions be thrown as Exceptions when called from > an OO syntax."
I'm undecided on whether it's advisable to throw E_WARNINGs as exceptions. I think that all but engine-consistency-affecting E_ERRORs should be exceptions, but that's a different discussion.
> Either i'm missing the point or we are agreeing this shouldn't be so.
You were saying that not doing this was consistent with other languages. I was saying that it was not. George

Sterling Hughes

22 years ago
On Apr 12, 2004, at 11:35 AM, George Schlossnagle wrote:
> > On Apr 12, 2004, at 2:14 PM, Sterling Hughes wrote: > >> >>> >>>> John has gone ahead and committed a perfect example of where >>>> exceptions just mess things up. In the tidy extension if you try >>>> and set an unknown configuration option it throws an exception. >>>> This is not by any stretch of the imagination an unrecoverable >>>> error, but rather a simple failure. Yet, if you use tidy in a >>>> script, and it is not within a try {} catch {} block your script >>>> execution will be terminated because the configuration option could >>>> not be resolved. This is much less than desirable and probably >>>> confusing for someone who doesn't understand what an exception or >>>> why he should care. >>> >>> I don't have a strong feeling about this either way, but to play >>> devils advocate: You requested an option be set. That option could >>> not be set because it is impossible to set a non-existent option. >>> How do you know how someone wants to handle that error? >>> >> >> I assume they don't want their script to stop executing, their >> transactions to be rolled back and a nasty error page shown : >> >> "Uncaught exception, could not set tabsize to 2 spaces" >> >> That could just be my crazy assumption though. > > It is. It's a hardocded portion of their app, and they made a > mistake. They may not care, but it's also possible that they do. > Assuming that they don't care enough to fix it seems equally crazy to > me. >
Could be a version mismatch with tidy, and a newer library. They develop there code, the option exists, and then someone with an older version of the library doesn't have that. Whether or not i have 4 spaces or 2 in my output is rather inconsequential. Now you deploy somewhere else and this explodes somewhere within a function and bumps the script out of a critical execution context and refuses to work.
>>>> You might argue that python or java would throw an exception in >>>> this case. For the majority of the java standard library and >>>> python code i have found this the opposite, however, even conceding >>>> that, PHP should never do this. We have the concept of warnings, >>>> in our world an error of this type does *not* terminate script >>>> execution. There are even less severe usages of warnings >>>> throughout the PHP source code, and there is no reason to convert >>>> them to exceptions. And if you don't, you still have the same >>>> inconsistencies. >>> >>> The discussion was on OO code throwing exceptions. Given that there >>> is very little OO core code in php4, I don't see a widespread >>> conversion happening. >>> >> >> No, this discussion was on having exceptions thrown instead of >> E_WARNINGs inside OO code. > > Rewind to the beginning of the discussion, the scope is not as broad > as you claim. >
I did. fast-forward to the end of this message, that's exactly the point john brought up.
>>> The key point that you're missing in all this is that _you_ don't >>> know what's a serious error and what's not. Only the developer >>> knows. For instance, the python smtplib can throw any number of >>> exceptions based on bad connect data or bad command responses. Is >>> this a 'serious' error? It depends. If sending a mail is an >>> inconsequential part of the app, maybe it's just an informational >>> warning. It's also easy to imagine it being a very critical, >>> non-recoverable error. The severity of the error lies entirely in >>> the purview of the receiver. >>> >>> Nothing sums this up for me better than KeyError, which is almost >>> never fatal in my applications but which constantly bites me in the >>> ass. Obviously your experiences may differ, which is really the >>> whole point. >>> >> >> Well, you can use get() now and be happy. :) > > I could, I could also catch my exceptions. There are plenty of other > exceptions (casting errors, etc) that will irk me whenever I use > Python. >
I've probably written a considerably large amount of python and I haven't run into this rampant exception problem you talk about. Could also be the reason why I like Python more than you... ;) It makes sense that overloads would cause exceptions, as it does with type casting exceptions - remember, python is a strongly typed language, that type schiznizzle is important to them.
>> >> I'm not saying that exceptions should never be used. But, John >> suggested "As a matter of consistency, I would like to suggest that >> for those extensions which have a OO/procedural syntax that the >> non-fatal errors >> generated by those extensions be thrown as Exceptions when called >> from an OO syntax." > > I'm undecided on whether it's advisable to throw E_WARNINGs as > exceptions. I think that all but engine-consistency-affecting > E_ERRORs should be exceptions, but that's a different discussion. >
I would probably agree with you on E_ERRORs.
>> Either i'm missing the point or we are agreeing this shouldn't be so. > > You were saying that not doing this was consistent with other > languages. I was saying that it was not. > >
Ok, then we disagree. I think its entirely inconsistent because the two systems don't map to each other, and you get plenty of cases where the two simply don't map. John is talking about *all* E_WARNINGs in OO code, and in the procedural variants, sending E_WARNINGs. The scope of E_WARNING is not in my opinion the same scope as an exception in any language, and we may just have to agree to disagree. -sterling

George Schlossnagle

22 years ago
On Apr 12, 2004, at 3:06 PM, Sterling Hughes wrote:
>> >> It is. It's a hardocded portion of their app, and they made a >> mistake. They may not care, but it's also possible that they do. >> Assuming that they don't care enough to fix it seems equally crazy to >> me. >> > > Could be a version mismatch with tidy, and a newer library. They > develop there code, the option exists, and then someone with an older > version of the library doesn't have that. Whether or not i have 4 > spaces or 2 in my output is rather inconsequential. Now you deploy > somewhere else and this explodes somewhere within a function and bumps > the script out of a critical execution context and refuses to work.
Setting an option has semantic meaning. Whitespace has no semantic meaning in PHP. These are apples and oranges.
>> >> Rewind to the beginning of the discussion, the scope is not as broad >> as you claim. >> > > I did. fast-forward to the end of this message, that's exactly the > point john brought up.
He's talking about all E_WARNINGs in an OO context, not in an OO extension.
>> I could, I could also catch my exceptions. There are plenty of >> other exceptions (casting errors, etc) that will irk me whenever I >> use Python. >> > > I've probably written a considerably large amount of python and I > haven't run into this rampant exception problem you talk about. Could > also be the reason why I like Python more than you... ;) It makes > sense that overloads would cause exceptions, as it does with type > casting exceptions - remember, python is a strongly typed language, > that type schiznizzle is important to them.
I'm not arguing whether it's important to them. I'm arguing that things that are not important to my app generate exceptions in Python. Something can be important in a language but not important to my app.
>>> Either i'm missing the point or we are agreeing this shouldn't be so. >> >> You were saying that not doing this was consistent with other >> languages. I was saying that it was not. >> >> > > Ok, then we disagree. I think its entirely inconsistent because the > two systems don't map to each other, and you get plenty of cases where > the two simply don't map. John is talking about *all* E_WARNINGs in > OO code, and in the procedural variants, sending E_WARNINGs. The > scope of E_WARNING is not in my opinion the same scope as an exception > in any language, and we may just have to agree to disagree.
The not-mapping issue is a serious one. PHP's procedural error-handling does not map well to Java or Python. PHP's OO error-handling can. The former can't change, the latter can. I don't think there's a clean answer. And before I incur a rant from Sascha about how I ramble endlessly without point, I'll resign from this argument. George

Andi Gutmans

22 years ago
I think the main reason for all of this disagreement, is because PHP (pre-exception state) is not consistent with its error levels. As mentioned here, sometimes relatively serious errors are E_WARNINGs and some less serious errors are E_ERRORs. Now say, we'd map all E_ERRORs (which can be recovered from) to exceptions, functionally this would not be very problematic because for people not using exceptions they'd still get a fatal error and it would allow people who want to work with exceptions to take advantage of them. However, as stated the fact that PHP is inconsistent with its error levels would probably limit the usefulness of such a change because it'd probably lead to quite a few inconsistency. I think the people here who argue that exceptions suck are quite wrong. In most cases, you expect your code to work perfectly. If it doesn't, I don't think you usually want it to continue its regular control flow. Rather, it'd be easier to catch the exception and give some kind of useful error message. Exceptions allow you to get rid of all of those if() statements that check function return values (due to it being a headache many developers leave those out) and to handle errors in a centralized place for logging and outputting a nice error screen. After all they should be used for real errors and not for control-flow. I think people who argue that exceptions suck probably aren't the people who check every return code of their functions or they'd be completely pissed off with that error model. Personally, I am not sure what my take on this is as I think most of us agree that it's a mess and there's no perfect solution. In an ideal world, I would prefer to write DB connection/query/disconnection code without having to check their return values, and if an error occurs, catch that exception and give a meaningful error message. However, it seems that finding the right solution for PHP is going to be pretty hard. Thinking out loud, it might be interesting to think of some automatic wrapping API, which could be used in order to use exception based PHP vs. regular PHP. However, doing this in a way which is accurate and automatic, especially as relying on our current E_* doesn't seem to be a good option, would be quite hard. Andi

Adam Maccabee Trachtenberg

22 years ago
On Mon, 12 Apr 2004, Andi Gutmans wrote:
> I think the main reason for all of this disagreement, is because PHP > (pre-exception state) is not consistent with its error levels. As mentioned > here, sometimes relatively serious errors are E_WARNINGs and some less > serious errors are E_ERRORs.
I agree. One programmer's E_NOTICE is an another's E_ERROR. However, right now, all non-fatal errors are essentially trapped (or ignored) the same way. [snip discussion on the merit of exceptions]
> Personally, I am not sure what my take on this is as I think most of us > agree that it's a mess and there's no perfect solution. In an ideal world, > I would prefer to write DB connection/query/disconnection code without > having to check their return values, and if an error occurs, catch that > exception and give a meaningful error message. However, it seems that > finding the right solution for PHP is going to be pretty hard.
I think the other problem is that we cannot come to a general consensus on the appropriate application of exceptions. There are some developers who would prefer they're *never* used. There are others who want to use them *always*. This isn't good. :) Until we can forge some middleground on *why* we should use exceptions, it's hard to come up with a solution for how we should go about solving the messy real world issues of legacy code, different error levels for similiar problems, etc, etc. Currently, as I see it, exceptions are maybe useful for application-level problems, but not for lower level errors. Essentially, you can use exceptions to handle errors in your own components, but not in any of the underlying extensions. Maybe this is how we want people to use exceptions in PHP, but I'd prefer this to be an overt decision instead of a side-effect of inconsistent extension deployment.
> Thinking out loud, it might be interesting to think of some automatic > wrapping API, which could be used in order to use exception based PHP vs. > regular PHP. However, doing this in a way which is accurate and automatic, > especially as relying on our current E_* doesn't seem to be a good option, > would be quite hard.
There are no excellent options here, but maybe we can come up with one that is good enough. -adam
-- adam@trachtenberg.com author of o'reilly's php cookbook avoid the holiday rush, buy your copy today!

Greg Beaver

22 years ago
Andi Gutmans wrote:
> I think the main reason for all of this disagreement, is because PHP > (pre-exception state) is not consistent with its error levels. As > mentioned here, sometimes relatively serious errors are E_WARNINGs and > some less serious errors are E_ERRORs. Now say, we'd map all E_ERRORs > (which can be recovered from) to exceptions, functionally this would not > be very problematic because for people not using exceptions they'd still > get a fatal error and it would allow people who want to work with > exceptions to take advantage of them. However, as stated the fact that > PHP is inconsistent with its error levels would probably limit the > usefulness of such a change because it'd probably lead to quite a few > inconsistency. > > I think the people here who argue that exceptions suck are quite wrong. > In most cases, you expect your code to work perfectly. If it doesn't, I > don't think you usually want it to continue its regular control flow. > Rather, it'd be easier to catch the exception and give some kind of > useful error message. Exceptions allow you to get rid of all of those > if() statements that check function return values (due to it being a > headache many developers leave those out) and to handle errors in a > centralized place for logging and outputting a nice error screen. After > all they should be used for real errors and not for control-flow. I > think people who argue that exceptions suck probably aren't the people > who check every return code of their functions or they'd be completely > pissed off with that error model.
I don't think that exceptions suck, but I agree that they are limited in their usefulness, just as you describe in the first paragraph. The majority of error conditions aren't severe enough to need them. Unfortunately, many developers I have talked to about exceptions plans to use them for just about every kind of error condition, and they expect them to be useful as such. I suspect this is because it is possible to differentiate between error type, and even severity, just through the class of the exception. Perhaps some kind of non-fatal exception equivalent could be worked out for 5.1/5.2? if continue or return was extended to allow returning from a catch to the point of execution after the throw statement, this would of course open a can of worms, but it might solve the issue. Obviously this would have to fail for any internal throw(), and be possible for user-level throw() only. Alternatively, it could return to the first user-level statement following the internal throw(). Greg

Derick Rethans

22 years ago
On Tue, 13 Apr 2004, Greg Beaver wrote:
> I don't think that exceptions suck, but I agree that they are limited in > their usefulness, just as you describe in the first paragraph. The > majority of error conditions aren't severe enough to need them. > Unfortunately, many developers I have talked to about exceptions plans > to use them for just about every kind of error condition, and they > expect them to be useful as such.
Then they are abusing exceptions big time. Throwing exceptions for E_ERROR conditions *might* be a good idea, but for anything lower than that: no way. This also means that extensions usually should not throw exceptions at all, as they are not supposed to throw E_ERRORs that abort scripts right away. Derick

Christian Schneider

22 years ago
Derick Rethans wrote:
> Then they are abusing exceptions big time. Throwing exceptions for > E_ERROR conditions *might* be a good idea, but for anything lower than > that: no way.
I agree wholeheartedly. Having worked with (Java) exceptions I realized that it is a _very_ hard instrument to use properly and if used poorly makes things *really* messy. Even after developing Java for over one year (with 10 years of programming experience in other languages) I was still not at the level where I could decide where to throw and where to catch exceptions without serious evaluation of the system. New concepts (like PPP and exceptions) might be valuable in some contexts but they are _not easy_ to use and the common PHP developer *MUST NOT* be forced to use them. You might think I'm kidding about PPP being hard but believe me: Using the right access level for methods is not trivial as soon as you build a framework and then both use and extend it. PPP and exceptions are *not* required to write even medium size applications (several 10k of lines), only DoD-style environments should _enforce_ such mechanisms.
> This also means that extensions usually should not throw > exceptions at all, as they are not supposed to throw E_ERRORs that abort > scripts right away.
Just curious: Is there such a policy right now? If so then this policy should be extended to exceptions. My .02 CHF, - Chris

Derick Rethans

22 years ago
On Tue, 13 Apr 2004, Christian Schneider wrote:
> > This also means that extensions usually should not throw > > exceptions at all, as they are not supposed to throw E_ERRORs that abort > > scripts right away. > > Just curious: Is there such a policy right now? If so then this policy > should be extended to exceptions.
It's supposed to be a policy, it was discussed some (long) time ago. Derick

Marcus Börger

22 years ago
Hello Derick, Tuesday, April 13, 2004, 9:28:38 AM, you wrote:
> On Tue, 13 Apr 2004, Greg Beaver wrote:
>> I don't think that exceptions suck, but I agree that they are limited in >> their usefulness, just as you describe in the first paragraph. The >> majority of error conditions aren't severe enough to need them. >> Unfortunately, many developers I have talked to about exceptions plans >> to use them for just about every kind of error condition, and they >> expect them to be useful as such.
> Then they are abusing exceptions big time. Throwing exceptions for > E_ERROR conditions *might* be a good idea, but for anything lower than > that: no way. This also means that extensions usually should not throw > exceptions at all, as they are not supposed to throw E_ERRORs that abort > scripts right away.
This brings us back to an old problem the severity levels are inconsistent. And further more we decided some time back that E_ERRORs shouldn't be converted to exceptions because of a few E_ERRORs that might not be continuable. From my point of view we should do two things: 1) convert the non continuable E_ERRORs to a higher severity (if there are any at all) 2) Use exceptions when a ctor needs to advertise its failure and in other places where exceptions are really usefull. Too much exception is a bad thing anyway.
-- Best regards, Marcus mailto:helly@php.net

Adam Maccabee Trachtenberg

22 years ago
On Tue, 13 Apr 2004, Marcus Boerger wrote: Hello Marcus --
> This brings us back to an old problem the severity levels are inconsistent. > And further more we decided some time back that E_ERRORs shouldn't be > converted to exceptions because of a few E_ERRORs that might not be > continuable. From my point of view we should do two things: > 1) convert the non continuable E_ERRORs to a higher severity (if there are > any at all)
Is there a reason not to move non-continuable E_ERRORs to E_WARNINGs? This prevents us from adding another severity level and also allows us to make all E_ERRORs fatal in the process.
> 2) Use exceptions when a ctor needs to advertise its failure and in other > places where exceptions are really usefull. > > Too much exception is a bad thing anyway.
There's so much anti-exception sentiment on this list, I wonder how they ever made it into PHP 5 in the first place. :) But, seriously, besides for ctors, when do people here expect developers to use exceptions? -adam
-- adam@trachtenberg.com author of o'reilly's php cookbook avoid the holiday rush, buy your copy today!

Christian Schneider

22 years ago
Marcus Boerger wrote:
> 2) Use exceptions when a ctor needs to advertise its failure and in other > places where exceptions are really usefull.
... and make the exception in the ctor an option, not the default IMHO.
> Too much exception is a bad thing anyway.
Yes, it has to be a really severe error, otherwise you start putting try/catch everywhere making your code ugly and your error handling unmaintainable. We should try to help people resist the temptation of exceptions as they are a dangerous thing if not used very wisely (-:C - Chris

Stanislav Malyshev

22 years ago
GB>>I suspect this is because it is possible to differentiate between GB>>error type, and even severity, just through the class of the GB>>exception. Perhaps some kind of non-fatal exception equivalent could GB>>be worked out for 5.1/5.2? That would be contradiction in terms. Exception means - "somettthing so bad happened that there's no point to continue locally - the current task has failed beyond repair". If the caller of the task thinks that this sub-task failure is not that bad and the top-level task can still go on, it catches the exception and handles it. From this point of view, I would use exceptions only to signal a very serious error condition - e.g., for DB library it would be DB connection missing (since it is not likely for any function to work after that), etc. GB>>if continue or return was extended to allow returning from a catch to GB>>the point of execution after the throw statement, this would of course GB>>open a can of worms, but it might solve the issue. Obviously this would I don't think it's possible. Exceptions unroll the stack, and once it's unrolled, you can't re-roll it back there. It just doesn't exist anymore. And we don't really want to enter the domain of context-switches inside PHP.
-- Stanislav Malyshev, Zend Products Engineer stas@zend.com http://www.zend.com/ +972-3-6139665 ext.109

Ard Biesheuvel

22 years ago
> Exceptions in languages like Java are used explicitly to catch fatal > errors, not to catch basic errors. Converting warnings to exceptions > would change the meaning of a warning from something which is nice for > development, or logging purposes, but handled by your control flow, into > an unrecoverable error.
Exceptions enable the user (as in: the programmer as user of a certain API) to decide which conditions qualify as fatal and which do not. For example, an SQL parse error would be fatal in an app where the SQL is hardcoded, but would be a valid error condition in an app that allows user entry of SQL statements. Stating here which errors are fatal and which are not is therefore pointless. Being able to only handle the error conditions that you can reasonably expect, and ignore the others, is the whole purpose of providing exception handling in the first place. Having the whole PHP OO API return false for every error without giving the nature of the error defeats this purpose entirely. Therefore, IMO, proper implementation of exception handling should at least provide exception functionality for the entire OO API, and maybe even for the procedural API as well, as they're not interchangeable, meaning OO apps will use the procedural API as well. I'm well aware that this is not going to happen, so maybe a compromise would be possible. Perhaps a zval type IS_ERROR that evaluates to FALSE for most common purposes, but can be used to identify the actual error condition that occurred, or the ability to pass more context to a user-defined error handler could be considered ? And for the E_WARNINGs, maybe a built-in Exception specialization (ie. NonFatalException) that is ignored by the top level catch() ?
-- Ard