http://qs321.pair.com?node_id=130739


in reply to CGI Error Handling

One thing to keep in mind is the difference between development/debugging error messages, and the user friendly error messages that should be displayed to actual users. Most users don't know what to do with a stack trace or a DBI error message - and as someone else already mentioned, that can be a security risk. Useability folks will scream if you mention anything technical in an error message.

On the other hand, carp, die() and company are your friends during dev.

I like to wrap most everything in eval{} blocks so that major errors can be wrapped with user friendly text, and uses UNIX::Syslog to log error messages. This gives me the chance to grab the $DBI::errst which typically has some great debug info in it for db errors.

This works great for production, but we tend to leave the eval{}'s out while first coding something - verbose error messages are a big help while debugging. Unfortunately, doing anything as a two pass operation means sometimes the eval{}'s don't get added before it goes to production.

Replies are listed 'Best First'.
Re: Re: CGI Error Handling
by uwevoelker (Pilgrim) on Dec 11, 2001 at 01:47 UTC
    I like the idea of putting code in eval-blocks, but is this also efficient/state-of-the-art/perlish?
    eval { open(FH, $file) or die "NO_OPEN"; $text = join('', <FH>) or die "NO_READ"; close(FH) or die "NO_CLOSE"; } if ($@) { ... }
    instead of
    open(FH, $file) or &error("NO_OPEN", $file, $!); my $text = join('', <FH>) or &error("NO_READ", $file, $!); close(FH) or &error("NO_CLOSE", $file, $!);
    What approach do you find better?
      You can (as in "have the potential to be able to") recover in the eval block. Can you recover in your error sub? I find the block more flexible that way, if that's the sort of thing that's necessary.

      (Feel free to drop the leading ampersand. It doesn't add anything in this case, and is often better removed.)

      In your example, the second option is actually more readable. But if the function call on the left is longer, and you start wrapping things will get pretty ugly. What's more, if you do something like $sth->execute and the transaction fails (e.g. from bad SQL or an RI constraint) $sth->execute will call die() for you - and an eval block is the only way to catch it.

      I prefer to use the same method for something every time - so I go for nothing but eval blocks. Using two different constructs to do the same thing in the same bit of software just makes things harder to maintain. YMMV.