Re: Exception misinformation

From: Date: Tue, 06 Jul 2004 23:07:15 +0000
Subject: Re: Exception misinformation
References: 1 2 3  Groups: php.pear.dev 
Request: Send a blank email to pear-dev+get-31680@lists.php.net to get a copy of this message
On Tue, 06 Jul 2004 18:55:00 -0400, Hans Lellelid <hans@velum.net> wrote: > Hi Justin, > > Some good comments here -- and indeed your example below highlights some > challenges. > > > > 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. > > Ok, fair enough. Remember too, though, that you can > set_exception_handler() to have a nice error if all else fails -- e.g. > redirect to error page if it's a web application. Doesn't really change > the fact that the error was fatal, but considering there wasn't any docs > for set_exception_handler() last I looked, it probably needs mentioning. > Well, that would be a nice addition. There really should be a PHP5 manual out there in parallel with the PHP4 manual. Or at least all PHP5 functions should be in the manual as PHP5 only. Although an outside try/catch would be the same, right? > > > 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. > > Yes, i think this is the main reason why exceptions are great. The > immediate jump to catch block is good (well, I think so), but the bubble > up is ingenious. That said, it should be an obligation of your code to > explicitly declare that exceptions may bubble through. > > > 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. > > I'll grant that it is harder to have error just ignored when you are > throwing them. You can ignore errors but it takes more work, that's > true. I would still argue that having a system that forces handling is > going to eliminate far more headache in the long run. > Yes, this is true. It just makes rapid prototyping a little harder. Not much, though. > >>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. > > Yup, me neither. I think warnings/notices is fairly insignificant. Not > that many apps use warnings/notices & not that many calling apps care. > > > [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. > > Yes, that is true; it can be harder to follow. Good documentation is > definitely a strong requirement for any package that uses exceptions. > > > 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. > > Yes, here I think you've identified the place where things get really > tricky. This logic is very hard to handle using Exceptions and can > sometimes be very kludgy. Also, I would agree that this is using > exceptions as error handling. In most cases faced with such a scenario > I would say that it needs to be redesigned. > > Also, I would point out that using PEAR::isError($obj) with if/then/else > statements is really still using error handling as flow control, and > shouldn't be considered "ok" while try/catch is "bad". > > The immediate thing that leaps to mind is that you should "look before > crossing the street" (I made that up, but it seems to fit :) I think > that you agree with me (below), but I'll illustrate, anyway: > > i.e. > > $file = array_shift($files); > while(!file_exists($file)) $file = array_shift($files); > // this isn't 100% correct, but you get idea > > $pkg->performAction($file); > > In general, by checking things more thoroughly you can avoid many of > these issues. > Yes, this would be the right way for files, but you saw my example below, which is a better one. > > 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. > > Well, that does further complicate things :) -- getting into some > pretty fring cases here, but it's a good challenge. > > In this case you do kinda have to use exceptions as flow control since > you actually are basing your logic on errors. > > Well, on the other hand, you could probably design your code in such a > way so that you didn't have to use nested try/catch blocks. For > example, identify that what you are describing is a number of loading > mechanisms for a particular file resource. Create different strategy > classes for the different ways that this file can be loaded: > > $loaded = false; > while(!$loaded) { > try { > $strategy = array_shift($loadingStrategies); > $strategy->load($file); > $loaded = true; > } catch (Exception $e) {} > } Yes, I thought of this as well. Yours would loop forever if none that worked, though. Maybe something like this: $loaded = false; $strategy = true; $exceptionMessages = ''; while(!$loaded && $loadingStrategies) { try { $strategy = array_shift($loadingStrategies); $strategy->load($file); $loaded = true; } catch (LoadingException $e) { $exceptionMessages .= $e.getMessage(); } } if(!$loaded) { throw new LoadingException('No loading strategies worked. '.$exceptionMessages); } -- DB_DataObject_FormBuilder - The database at your fingertips http://pear.php.net/package/DB_DataObject_FormBuilder paperCrane --Justin Patrin--

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