Re: Exception misinformation

From: Date: Tue, 06 Jul 2004 20:54:29 +0000
Subject: Re: Exception misinformation
References: 1  Groups: php.pear.dev 
Request: Send a blank email to pear-dev+get-31670@lists.php.net to get a copy of this message
On Tue, 06 Jul 2004 15:37:18 -0400, Hans_L <hans@velum.net> wrote: > There seems to be a lot of (m|d)isinformation about Exceptions on this > list. I urge those of you involved in these discussions about > Exceptions to actually try using them -- build an application with them. > I have used exceptions, PEAR_Error, and other stack-based approaches > in PHP and I am not using Exceptions because they are a "trend", but > because they have helped me solve patterns faster, write cleaner code, > and better handle errors. > Yes, there are many strong points to Exceptions. They do make some things easier. > Here's an attempt to correct what I feel are bits of misinformation from > recent discussions. > > 1) Exceptions are not FATAL. They are designed to be caught; for an > exception to become a fatal error is for a programming error to have > been made (i.e. not catching). Calling private methods from outside of > an object context also results in an E_FATAL error; does this mean that > private methods are fatal? And, as mentioned below, forgetting to call > PEAR::isError() on a returned object & then attempting to invoke a > method will also result in fatal error. Is PEAR_Error also only for > fatal errors, then? > They're not fatal, but they do have Fatal tendencies. To react well to an error with Exceptions, there may have to be many try/catch blocks. > 2) Using exceptions does not mean wrapping every method call in a > try/catch block. The idea with exceptions is that they allow you to > group things into logical units -- think of business transactions, or > Transaction Script pattern. try/catch blocks only need to exist where > you want them to exist. It allows you to decide what contexts are > relevant for exceptions. > > Here's an example [that I think I've given before]: > > function hydrate(ResultSet $rs) { > try { > $this->setName($rs->getString(1)); > $this->setEmail($rs->getString(2)); > $this->setLoginCount($rs->getInt(3)); > $this->setPicture($rs->getBlob(4)); > $this->setLastLogin($rs->getTimestamp(5)); > $this->setSignature($rs->getString(6)); > $this->setPassword($rs->getString(7)); > } catch (SQLException $e) { > throw new PropelException("Error populating Person object.", $e); > } > } > > (btw, imagine doing that with PEAR_Error...) Very true, that's hard to do with PEAR_Error. > > Of course the Person->hydrate() method can be invoked from larger blocks > that have no try/catch. > > Applications (particularly ones that use PEAR) are built in layers. The > strength of exceptions is that they move up the layers without needing > to be explicitly passed. This means that very low-level exceptions can > be passed up to high-level calling code with no additional effort by the > developer. I had never considered this before. This is a very nice thing, and would not be possible to fix, even with my Exception or Error proposal. > In some cases that is desireable, in other cases it may be > more desireable to catch and rethrow if you want to provide some more > information about the error. (As in the hydrate() method, which provides > some contextual information to the exception so that the error doesn't > simply ready "Illegal resultset offset: 1", for example). In either > case, having the exception is preferrable to code that is oblivious. > Yes, I agree. But it is nice to have the ability to simply ignore errors sometimes and see what the program does overall. With Exceptions, that's not possible without lots of extra try/catch blocks. [snip] > 4) No one is suggesting throwing WARNING or NOTICE exceptions. Warnings > and notices deserve their own handling system (or trigger_error()). > These have very little in common with exceptions, which are errors that > need to be *handled* by the calling code. > Although I rarely if ever see WARNINGS and NOTICES in PEAR packages. All errors are Errors. [snip] > > Hopefully that illustrates that it is never harder to catch or throw an > exception than it is to handle a return-code error. Feels silly to > explain this, but I do think many people need to see more examples of > this stuff (and perhaps use it!!). Yes, it's no harder to use. It *can* make code harder to follow, though. [snip] > > I think that there are definitely reasons to be cautious of using > exceptions, and I think it would be good to discuss those. E.g. use of > exceptions as flow control, how packages should re-throw or wrap > exceptions from other packages, guidelines for when it is appropriate to > throw exceptions, how packages should subclass extensions, how they > should be documented. This is a point that *must* be talked about. Especially "using exceptions as flow control". What does this mean exactly? Let's say that a package throws a file not found exception. Perhaps I want to try another file (or group of files), meaning a loop in the code based on whether an exception is caught. This is pretty ugly. But the file not found exception is an error and therefore an exception for the class I'm calling. Or say that if a file isn't found, I want to switch to an alternate method of getting the information I need? If file not found is too easy to get around for you (file_exists), then consider trying to connect to an FTP server. If it fails, use a file on the filesystem, or possibly us eanother method. If the FTP class throws an exception, I'm forced to use that exception to change the flow of my code. There is simply no way of getting around that. How can this be resolved? I don't see any good way. If we use Exceptions for Errors, some people will be forced to use them for this kind of flow handling. -- DB_DataObject_FormBuilder - The database at your fingertips http://pear.php.net/package/DB_DataObject_FormBuilder paperCrane --Justin Patrin--

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