Following this useful Advent about Dancer::Exception:
I am attempting to refactor exception handling in a large D1 app, using
Dancer::Exception.
Ideally I’d like to Raise Friendly => ‘Some Friendly Error Message’ to
report user-friendly error messages without logging, and everything else
(whether raised by Dancer, die(), or by something else such as a database error)
should just report “Internal Server Error” and log it.
Furthermore, I’d like to be able to use Raise Friendly => ‘Some Friendly
Error Message’ anywhere within the route code or within any package used by the
route (example below uses Some::Package).
See code below. It *appears* to work for all shown cases (1, 2,
3a-3d), but I would really appreciate critique and recommendations. In
particular:
1. I don’t want to repeat the same catch {} section within every single
route (following principles of D.R.Y.), so would really appreciate
recommendations for cleanup. I tried using hook before_error_init and
before_error_render but got nowhere fast (maybe I shouldn’t have given
up?)
2. Am I using register_exception(‘Friendly’); correctly? I get a
compilation error if I attempt to register_exception(‘Friendly’); within
Some::Package.
3. Following D.R.Y., it would be nice to not have to
register_exception(‘Friendly’) in every single route. I tried declaring it
within app.pl but got the expected compilation error.
Thanks all,
Hermann
---
package mytest;
use strict;
use Dancer ':syntax';
use Dancer::Exception qw(:all);
register_exception('Friendly');
use lib "/home/s1/modules";
use Some::Package;
get '/' => sub {
try {
# Case 1
Raise Friendly => ‘Friendly within mytest’;
# Case 2
die ‘Unfriendly within my test’;
# Case 3a-3d
&Some::Package::Test();
}
catch {
my ($exception) = @_;
if (ref($exception) =~ /^Dancer\:\:Exception/) {
if ($exception->does('Friendly')) {
status 400;
return "got a friendly
exception: " . $exception->message;
}
warning 'got an unknown exception to
rethrow';
$exception->rethrow;
}
die $exception;
};
};
----
package Some::Package;
use Dancer ':syntax';
use Dancer::Plugin::Database;
use Dancer::Exception qw(:all);
return –1;
sub Test {
# Case 3a:
raise Friendly => 'A friendly error within Some::Package’;
# Case 3b:
die ‘Unfriendly within Some::Package’;
# Case 3c: database error (unfriendly)
database(‘mydb’)->selectrow_array("SELbarfECT 1");
# Case 3d: Some other package
&Some::Other::Package::Test();
};
-----
And for completeness, app.pl:
use strict;
use Dancer;
use mytest;
dance;