Re: [RFC] Errors and handling in PEAR
| From: | Greg Beaver | Date: | Thu, 31 Jul 2003 22:11:50 +0000 |
| Subject: | Re: [RFC] Errors and handling in PEAR | ||
| References: | 1 2 | Groups: | php.pear.dev php.pear.qa |
| Request: | Send a blank email to pear-dev+get-19104@lists.php.net to get a copy of this message | ||
Matthias Nothhaft wrote:
Hi all, Greg Beaver wrote:That's fine. I find that the 2 letters just feel good when I have to type "PHPDOCUMENTOR_" in front of it :). I wish there was a way to do a shorter prefix for constants, it's really annoying, but that has nothing to do with errors :)Hi, I'd like to propose a new way of thinking about error-handling to amend the discussion started earlier. 1. All packages that raise unique errors must define special error constants with a prefix of the package name followed by ERR_, as in PHPDOCUMENTOR_ERR_INVALID_TAGOk, but why not write out ERROR ? I think two letters are not much more overkill ;-) But it makes clear the constant's use!
What do you exactly mean with "unique"? Unique in the package or unique in PEAR?Let me try a rewording: 1. All packages that define new errors must define special error constants with a prefix of the package name followed by ERR[OR]_, [depending on what is decided] as in PHPDOCUMENTOR_ERR[OR]_INVALID_TAG. Note that the use of pre-defined constants from other packages such as DB_ERROR, does not require redefinition. and then re-phrasing 3. 3. All packages that define new errors as noted in point [1.] must extend PEAR_Error...
The point of a warning or notice is that execution should continue. If you return, then it can't. For instance, in phpDocumentor, often there will be an assumption made, especially regarding packaging. If a class has no @package tag in its docblock, then phpDocumentor assumes it belongs to the default package, or the package of the parent class. This is not always correct. For instance, in phpDocumentor's code, we extend the HTML_TreeMenu_Node class, but our extended class is not part of the HTML_TreeMenu class. It is important to raise a warning so the user knows that an assumption has been made, and can correct it if necessary. If we were to just stop parsing documentation when a class has no @package tag, that would make no sense - the package assumption is not an error most of the time, and even when it is, it only affects where the documentation is located, not the correctness of the documentation. So, we raise a warning, and continue parsing. It is the end application's job to register a callback function that catches the warning and logs/displays it. I hope this is clearer. Having a standard system for doing warnings/errors will make PEAR even better, as it will be possible to handle all the possible incorrect situations, not just fatal ones.2. Error constants will never be referred to by number, only by constant name. To resolve conflicts between packages, the returned error's getType() method must be used to determine which package an error came from. 3. All packages that raise unique errors must extend PEAR_Error with an error class named Package_Error, as in PhpDocumentor_Error, and must use this error class in returning all unique errors. If there is a difference between an error and exception, the Package_Exception class should be defined and used to throw a fatal exception. An example of this difference is a fatal documentation error in PhpDocumentor (error), and an invalid input to a function in PhpDocumentor (exception). 4. It is suggested to define Package_Warning and Package_Notice classes for those packages that need to pass warnings and notices to a callback function, to allow non-fatal but potential errors to be ignored, or displayed and/or logged as necessary. These should be called using PEAR::raiseError() without returning the warning/notice, to allow a callback function to catch the information for logging/display. 5. Only errors and exceptions should be returned. If an error must terminate the program execution, it is an exception. If an error must terminate the current function, but not the program execution, it is an error. If an error is a problem that need not terminate execution, or might be questionable but intended behavior, a warning should be used (for example, deprecated methods). If an error is simply a valid situation that could lead to other more serious errors, it is a notice.I think this is a little bit complicated... Why not return Warnings and Notices? Why separate Exception and Error/Warning/Notice?
I think it's important to find a solution for both: php4 and 5! Because it will last a long time til anyone of us will use php5 in all projects! (But we all want a better error handling now!)This is exactly why I want to do this - exceptions ARE different from errors in some packages.
It is very important to find a way to integrate the new error handling features of php5/ZE2 into PEAR's error handling! This is the right time now to think about it...This is already done, the new error mode PEAR_EXCEPTION uses Zend 2 exceptions.
But you/we forgot the fact why I reinitiated this discussion: I want the packages to return error codes in all errors! Again: The missing error codes in many packages makes it impossible to integrate such packages into professional projects/applications! Why? In such projects/apps errors mustn't be displayed to the user like "db connection failed" or "file not found" because this has nothing to do with a well thought usability! And it is not really userfriendly when such an error leads to a hard exit/die of the script and there is only displayed a broken part of a html page... An example is Archive_Tar: I can not integrate that package into my projects because it provides no error codes only messages I do not wanna show my users! A common way to define constant names would also be great but I think the most important problem of the error handling is that error codes are not completely supported in PEAR.OK, I forgot to specify this, but I was assuming all the details about error constant naming conventions would imply this (oops :) 6. All errors must include at least an error code (the constant discussed in [1.]) and an error message. Now, an important and intentional omission from my original post was defining numbering conventions - it should NEVER be necessary to directly acces the number code by number, as in: if ($err->getCode() == 6) { ... } The only way to guarantee this is to use a different error class for each project. This will also fit in with Zend 2 better because then this code will specifically catch DB errors: catch (DB_Error $e) { } I'll revise the RFC and send it out with the changes you're talking about. Greg