Masem has asked for the wisdom of the Perl Monks concerning the following question:

Easily, when you use any perl function or package that uses the system in some way, including but not limited to, opening files and using databases, everyone's got the standard or die 'some error' as to exit as quickly as possible, and assuming one is under a CGI/web server environment, that error message is sent to error.log, which is great for the programmer in order for him to fix it. But you also will usually leave the user in a lerch with a "an error occured, please contact the webmaster..." deal if you simply use die.

Obviously, the next step is then to use a custom 'error' handler that you use instead of die. It can still dump the error message to error.log, but you can at least exit the program cleanly with a somewhat informative error to the user. However, this then brings up another problem: while certainly it's best to try to collect all system resource calls to as early as possible in the program before output is sent, this is not always possible particularly in database usage, and thus, you'd have printed a lot of your page, and then suddenly have this error message in the middle of it.

So the next logical step would then be to print all data that would have normally gone to STDOUT from the CGI call to a string or other temporary cache which is then sent all at once at the end of the CGI program to STDOUT. Errors that occur before this point can then be shown to the user on a 'clean' page even if they occured mid-CGI processing. While this is probably the best, you then introduce a big problem when programming as you could easily miss adding the cache storage area in print statements, or as some packages do like Template Toolkit, forget to give them an alternate target for some operations. This moves the problem more onto the programmer's shoulders than the user, but I can see it being very potentally bug-ridden.

So my question is basically, at what point is the error handling method typcially accepted by the user and by the programmer together? My inclination from other sites is that the somewhat descriptive but possibly in the middle of the page error message is typically acceptible by both programmer and user, but that's my current opinion. I'd be worried about all the errors that I could introduce by switching to the cache'd method.

The other related question: is it wise to necessarily let the user know directly of the error message? Some are sufficiently descriptive that while they easily narrow down the problem for the programmer, they could also be used by a malicious cracker or user to harm your system if they tried. Other non-malicious users will also just see a blob of undecipherable text on the screen, and will most likely simply shrug. I'd like to provide at least some clue as to what happened (say 'error in the database system', 'error in file operations'), which fortunately can be done if one handles their own errors instead of with die (pass in a keyword that indicates where the error was). Probably more importantly, I would want to include the localtime of the error and any other possible parameters that may or may not show up when I write to the error.log. Has anyone found any good guidelines for letting the end user know what's wrong?

Replies are listed 'Best First'.
Re: 'Clean' Error Handling from perl during CGI
by AgentM (Curate) on Feb 25, 2001 at 02:21 UTC
    I agree wholly with ichimunki but would also like to add these points.

    Again, conveying information like "database failed" is not useful to the user- so why print it? I do agree that printing an error in the middle of the page is ugly, so you don't want that either. If one does end up using something like that, then that person deserves to have it ugly because this person obviously did not do enough user input checking. The Tip of the Week:

    • Check user input for validity. Use taint mode.
    If the input passes a regex or some other test mechanism, let it through, otherwise alert the user that the input was invalid and throw that input away. Don't try to munge it or morph it into something useful- just nuke it. If you check your user input enough you should NEVER encounter a situation where you need to print an error message after printing out 50 rows of a table. If checking the input against a DBI-execute call is necessary, then do it. No sense in wasting your time later trying to figure out what happened.

    It may also turn out that your first user input check fails on multiple counts. This is all the more reason to log every error with specifics of the current variables information perhaps using Data::Dumper. That way, if an error along the way does occur, then you can immediately see and fix the problem.

    Take an example from perlmonks- don't hand out free error information. vroom is kind enough to send us seemingly uninformative integers as error "numbers". Apparently, he is able to run such number reports through a munger to retrieve some information about the error. At most, say, "Temporary System Failure" or something along those lines.

    Good Luck!

    AgentM Systems nor Nasca Enterprises nor Bone::Easy nor Macperl is responsible for the comments made by AgentM. Remember, you can build any logical system with NOR.
(ichimunki) Re: 'Clean' Error Handling from perl during CGI
by ichimunki (Priest) on Feb 24, 2001 at 18:02 UTC
    I am not a web developer, so take these thoughts with some consideration.

    Why not use a module like Carp to avoid use of die altogether? You'll generally get more helpful error messages this way, and then, for production you can easily switch Carp for a custom error handling package, without having to resort to handling the "real" error signals.

    I would personally prefer to have errors with web pages redirected to a static or bullet-proof script by the server, rather than try to have the error-prone script handle them. You see this a lot with 404, but it may not be appropriate in situations with more subtle errors happening behind the scenes.

    A good error message in your case will not tell the user anything other than, "You can't do that." If something the user has done is involved in the error, perhaps communicate this in terms that don't reveal your system's inner workings, but will allow them to understand what they need to do differently.