Re: Exception misinformation
| From: | Hans Lellelid | Date: | Tue, 06 Jul 2004 22:55:00 +0000 |
| Subject: | Re: Exception misinformation | ||
| References: | 1 2 | Groups: | php.pear.dev |
| Request: | Send a blank email to pear-dev+get-31679@lists.php.net to get a copy of this message | ||
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.
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.
Yup, me neither. I think warnings/notices is fairly insignificant. Not that many apps use warnings/notices & not that many calling apps care.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]Yes, that is true; it can be harder to follow. Good documentation is definitely a strong requirement for any package that uses exceptions.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.
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.
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) {}
}
Hans