Re: Re: cvs: pear-core /PEAR ErrorStack5.php Warning.php

From: Date: Mon, 06 Sep 2004 07:01:36 +0000
Subject: Re: Re: cvs: pear-core /PEAR ErrorStack5.php Warning.php
References: 1  Groups: php.pear.dev php.pear.core 
Request: Send a blank email to pear-dev+get-33235@lists.php.net to get a copy of this message
Hi, I'll try to respond to both emails at once :). I promised not to get dragged into polemical debates, but I guess I must respond to this email. If we still don't agree on anything after this, then I guess I will have to simply request that advocates of trigger_error() provide better solutions to these problems: 1) how to repackage a trigger_error() warning as an exception *with proper context*. This means providing some means of a PEAR_Exception cause that can be standardized and used in the case of a deep package usage hierarchy (for example think SOAP and its 4-level tree of dependencies). Put simply: how can you easily tell one trigger_error()ed warning from another without having to parse the error message? 2) how to standardize the use of trigger_error() warnings to provide context information to solve the last part of #1 I suggested on php-internals that it would be nice if you could pass an object to trigger_error() and have it retrieve the string representation using __toString() for error display, but pass the object to an error callback as an extra parameter, but got the usual "I don't see any code so I'm going to ignore that suggestion" response one expects from busy coders. This would actually solve #1 very nicely, as we could pass exceptions in, making re-packaging them very easy. Bertrand Mansion wrote:
Alan Knowles wrote:
I wish I had more time to look at it. The more I look at it, I get the feeling that if you need to pass information back to the caller, then perhaps it should have been using an exception. The idea of turning the Warning handler on/off to catch messages slaps of why arnt exceptions being used..
That's an obvious one: exceptions MUST exit the current context. A warning allows processing to continue when there is no actual error (non-fatal).
I suspect Warnings Should really be preventable by method arguments.. (either a extra arg 'dont warn me' / returning booleans - and logging only done to detect programming errors, rather than actually be dealt with.
This is not what I had in mind for warnings, that is to say warnings are not just to find programming errors, exceptions are more appropriate for these issues, warnings work better with input processing.
It reminds me a bit of a debugger in some respects..
although it could be used for this, I suppose.
I guess the big question is where does this fit in the equation of trigger_error("Some warning" E_USER_NOTICE); - an warning that should be preventable by checking args.. or telling the method that you know it might fail?
I'm not sure I completely understand the English you're using here, but I'll try to respond to what I think you're saying :). I am thinking of layering. PEAR is about making packages that can be used with dependencies. Sometimes these dependencies are several levels deep, so the "DB" package might be buried 2 or 3 methods deep from the current-package-level method MyPackage->doSomethingWithDB(). It might be the case that the intermediary packages don't care about warnings returned from DB. However, if MyPackage DOES care, and DB signals a warning using trigger_error(), how could it possibly detect where the warnings are coming from? If DB is the only package that could trigger a warning, no problem. But what if DB_Foo *also* triggers warnings? Suddenly, the package developer is forced to hack some absurdly awful-looking code that includes using set_error_handler() to temporarily catch any possible warnings, and to parse the _error message_ to determine the source of the warning. I have been forced to do this many times in my use of packages that use trigger_error(). Also, what may be a warning for one lower-level package might be an exception for a package that uses the lower-level package. Re-packaging the lower-level warning as an exception (using the PEAR_Exception cause) is really not practical with a trigger_error() handler. In addition, trigger_error() can be ignored ONLY on an application-wide basis, or handled ONLY on an application-wide basis. It is completely unsuitable for packages that may have dependency hierarchies.
throw PEAR_Exception() - a situation that is preventable by try()'ing.
and makes executing any code that might have followed the throw() impossible.
I tend to agree with Alan here. IMO, warnings are something that help you debug your code so no matter so it is important that you see them immediately when you are developing and can log them when in production. And this is something already supported by PHP natively (in the ini file).
Warnings can be much more than debugging code. They can be used for flagging suspect user input (debugging user's usage of your code). Complex packages can often be used in more than one way, and sometimes the choice means some input can be either completely valid but quirky, or invalid and really difficult to find the errors. Which it is often depends on what the user actually meant by their input. Using trigger_error() doesn't make any sense here, because you would be lumping developer-specific information (php errors/notices/warnings) with user-specific information (input debugging). Using an exception makes even less sense, as there is no logic error in the program itself - it can execute the user's wrong intentions with absolutely no conflict. This is just one example, if you really force me, I will continue to come up with them, but the fact is I am right and we can save some time if you will at least acknowledge that the problem exists so that we can move on to practical solutions. :)
I think we should really concentrate on PEAR_Exception and use trigger_error() for warnings. This would make everything lighter and easier to understand for the end-user than requiring him to deal with a new API.
The end-user would not have difficulty understanding the API for PEAR_Warning. It requires learning three methods PEAR_Warning::begin() PEAR_Warning::hasErrors() PEAR_Warning::end() (or whatever it ends up being called) Advanced users (those with greater needs) would be able to ask more of the API, and it would be there. trigger_error() is a dead end designed by procedural coders to help debug the PHP core. The fact that it was extended to help users is of great value to single-level procedural code, and of not much use at all to multi-level OO coders who rely on inheritance and other layerings to organize code. Greg

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