[cgiapp] Graceful Error Handling in CGI::App (compile / init stages)

Ron Savage ron at savage.net.au
Wed Jul 7 19:47:40 EDT 2010


Hi Mike

On Wed, 2010-07-07 at 10:16 +0100, Mike Tonks wrote:

> 2) If I hit an error in cgiapp_init, is there a way to redirect to an
> error page, as per prerun_mode() ?

If something specific can fail, eg insertion into a db:

use Try::Tiny;

...and...

try
{
	$message = $self -> param('db') -> site -> add($site);
}
catch
{
	$message = $self -> check_for_unique_error($site, $_);
};

If anything dies or errors, eg DBI because site names are have to be
unique as per the create table cmd, the error msg is in $_. Hence the
last param in the check...() call.

I just happen to have a special test for the word 'unique' in error msgs
(tested with Pg, MySQL, SQLite). But in general you wouldn't do that.

As others have said, don't let just any Perl error msg out, since it'll
identify module names and paths, and potentially the db server's brand,
etc (including that the code is in Perl!).

Also, for every project, I have a log table, and I now log entry to
every sub at the 'debug' level. The log level (1 for the whole project,
not per msg) is in the config file.

With a wrapper logging is now just $self -> log(debug => $msg) or
whatever level fits. Session ids, CGI form params, etc get (info =>
$msg).

Just be warned about a trap with SQLite.

When you use Log::Dispatch -> add() and Log::Dispatch::DBI -> new(),
SQLite hits the db immediately with the latter call, which causes a
problem with a new db, since the log table won't exist.

Other dbs don't do that. So, with SQLite, you need special code to 
create the log table before Log::Dispatch::DBI -> new(), if the table
doesn't already exist.
-- 
Ron Savage
http://savage.net.au/
Ph: 0421 920 622



More information about the cgiapp mailing list