Re: Standardized way of interpolating variables into PEAR_Exceptionmessages?
| From: | Justin Patrin | Date: | Sun, 24 Sep 2006 17:44:13 +0000 |
| Subject: | Re: Standardized way of interpolating variables into PEAR_Exceptionmessages? | ||
| References: | 1 2 3 4 5 6 7 | Groups: | php.pear.dev |
| Request: | Send a blank email to pear-dev+get-44036@lists.php.net to get a copy of this message | ||
On 9/24/06, Alan Langford <jal@ambitonline.com> wrote:
On 2006 09 24 06:51, Alexey Borzov wrote: Hi, OK, let's do a more polite rehash of what Bertrand already said. Pierre wrote:1) Error message strings have to be there in order to give any useful information to the developer. 2) We suggest that different errors be packaged as different exception classes, allowing the catcher to define whatever message they want. 3) We also support an error code parameter for our Exceptions, allowing them to be further differentiated.I *have* been using them for quite a bit of time, both in my own projects and now in writing HTML_QuickForm2. And I must admit it is much more natural than to write if (PEAR::isError($blah)) {And I confirm that this pepr is not accepted. We are not going to accept such changes with five +1, we never did and we will not start now. A large participation and agreement is required.The proposal is either accepted or not, whether the anonymous person on IRC likes it or not.Hey, you are Mr. PEAR Group, not me. If you want to make up new rules for accepting proposals then go ahead and make them up, but please follow due procedure [1] for this. The exceptions proposal was accepted 2 years ago, but people who supposedly have issues with it didn't try to do anything to fix these issues.What I say is to consider this draft as what we should use as rule for exceptions is plain wrong. If you have really tried them two years, you would not have proposed them as standard, really not....} after each call.A quick review of the comments [1] gave me 3 votes of -1, they are Stig's [2], yours [3] and one by Richard York [4]. Richard's comments do not give any specific objections to the RFC, so lets dissect Stig's comments and yours. Stig's: ---------- This document would be better suited as an introduction, it is not a comprehensive guideline. Despite the "Documenting Exceptions" and "Exceptions are part of the API" sections it is not specific enough to have any real meaning as a guideline. Things that are missing: * how to convert PEAR_Error and PEAR_ErrorStack type errors to exceptions * PEAR_Exception is mentioned but not defined * No guidance on when to re-use exising exception classes and when to create your own Requiring that each package declares one or more classes for exceptions gives no meaning, many packages will do just fine without this. IMHO the right place to start would be to define the PEAR_Exception API (or just state that it is identical to that of Exception), decide on a set of standard, general, exception classes, and how to convert PEAR errors to PEAR exceptions without losing any information. ---------- Most of the points raised here are now irrelevant. With the acceptance of E_STRICT RFC converting PEAR_Errors and ErrorStack errors to Exceptions is mostly not an issue since E_STRICT packages using exceptions will not depend on packages using PEAR_Errors. On the other hand the RFC gives an example of converting PEAR_Error to an exception, it is unclear how Stig missed that. PEAR_Exception class is now available and distributed in PEAR package. "No guidance on when to re-use exising exception classes and when to create your own" is stupid because each package is required to define its own exceptions, so the answer to reuse is "never". That's how they do it in Zend_Framework, by the way. The one and only point that makes sense is that some packages will not need exceptions and thus will not have to define their own exception classes. Now, with all due respect to Stig, if he ever bothered to write down such comprehensive guidelines before creating the abominations of PEAR and PEAR_Error base classes then we won't have to deal with BC in the first place. So voting -1 on this proposal without giving solutions is extremely impolite act of his. On the other hand, I don't think that automatic wrapping of PEAR_Errors will be too hard to add to PEAR_Exception. Now on to yours: ---------- "It was written to cope with Exceptions, introduced in Zend Engine 2 as the error handling mechanism." -1 from here, I do not like the idea to force the usage of exceptions as general errors hanlders. I failed to see why each single package should declare (or extends, or...) their exception classes. Why? I can imagine some without any kind of exceptions... "An error is defined as an unexpected, invalid program state from which it is impossible to recover." This is the definition of an exception. Where exceptions should be used (trying at least to die cleanly ;) ). But in no way the definition of an error. That's exactly where errors and exceptions differ. ---------- So the first point is that you don't like exceptions. That's OK, I don't like lots of stuff in PEAR, but if majority of developers like it then I have to comply. What prevents you from doing the same? As for your other 2 points, I do agree with both: * If a package does not throw any exceptions then it doesn't need to define its own exception class (that's what Stig wrote also) * The definition is indeed of the exception, not error. In a nutshell, fixing the supposedly huge issues with this RFC will require just 2 minor edits.Also a quick review of the comments will tell you how controversial is this proposal and how hard it is to define strong rules about this topic. I prefer guidelines and common sense.Trivial conversion can be done via throw new Foo_Exception($error->getMessage()); or the equivalent for PEAR_ErrorStack. As for automatic conversion tools, they are outside the scope of this RFC and should (probably) be coded as add-ons to PEAR_Exception.Also this proposal misses the conversion from other Errors (Error or ErrorStack ) to exceptions.Where exactly are these questions?Given the amount of questions about exceptions usage , when to use them,The RFC is extremely clear on this one.when to define your own classes or reuse a standard one (internal one),What exactly should be added to this guideline? [1] http://pear.php.net/pepr/pepr-votes-show.php?id=132 [2] http://pear.php.net/pepr/pepr-vote-show.php?id=132&handle=ssb [3] http://pear.php.net/pepr/pepr-vote-show.php?id=132&handle=pajoye [4] http://pear.php.net/pepr/pepr-vote-show.php?id=132&handle=richy I will start with a disclaimer that I'm still just scratching the surface of "PEAR under the hood", so it is likely that what I have to say displays either ignorance or misconceptions. I would appreciate (polite) correction and/or instruction when this occurs. I'm a little wary of adding on to a thread that has so much emotional content, but since I've been doing a lot of work with ErrorStack lately... One of the problems with most error/exception mechanisms is that they have a real inclination to take all the semantically meaningful data, jam it into an unparsable string, and pass it back as an error message.I strongly ask for a complete documentation *and* guideline in PEAR,
The other major problem is that exceptions tend to get repackaged as they go up the call stack to the originating application, and in many cases the last traces of the original semantic information are lost as the error message gets replaced by a higher level message. An example of this is a package that throws an exception "Cannot connect to server." while obscuring something useful like a "403 authorization failed." The first message may be adequate for an end user, but it's pretty useless for someone trying to diagnose the problem.Of course, this is an issue but not with PEAR_Exception. 1) If nothing is being added to an exception we suggest not catching and rethrowing it. 2) If an exception is caught and rethrown it *must* include the original exception as the cause. See the docblock for the constructor: /**
* Supported signatures:
* PEAR_Exception(string $message);
* PEAR_Exception(string $message, int $code);
* PEAR_Exception(string $message, Exception $cause);
* PEAR_Exception(string $message, Exception $cause, int $code);
* PEAR_Exception(string $message, array $causes);
* PEAR_Exception(string $message, array $causes, int $code);
*/
It also supports passing an array of exceptions as causes.
So each PEAR_Exception is, by definition, a nestable exception, as it should be.
As Greg observed, ErrorStack addresses both of these issues. The semantic information can be passed as part of an array of data, and the stack allows an application developer to trace the error to the original point of failure. What PEAR probably needs is some policy for standardization of common semantic data, so that everyone uses, for example, ['code'] to store an error code, and we don't have to determine if we are looking for 'code', 'error', 'errcode', or whatever on a package by package basis. Possibly the best thing to do is to embed some of these into PEAR_Exception.See above.
The internationalization of any final message has to be the responsibility of the application, and if the original semantic data is there, then the developer can easily use whatever mechanism they choose. Without the supporting semantic data, there's no practical way to internationalize. The actual I8N might be a PEAR supplied one, but in many cases, applications already have a way of addressing this requirement, and it makes little sense to force a developer to support both.-- Justin Patrin