Using Dancer::Exception -- searching for best patterns
Following this useful Advent about Dancer::Exception: http://advent.perldancer.org/2011/6 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;
On Tue, 2016-01-12 at 16:32 -0800, Hermann Calabria wrote:
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).
I wrote (with a little help) Dancer2::Plugin::LogReport for a comprehensive and easy way to do this and a bunch of other stuff, whilst keeping code to a minimum. I'm just about to post an article to the mailing list about it. I realise you're using Dancer1, but you might like to look at the techniques involved, or even consider porting it to Dancer1 if it would be of benefit to you.
1. I don’t want to repeat the same catch {} section within every single route (following principles of D.R.Y.),
That's exactly the idea behind the module - I got very bored writing code similar to that in your examples. Andy
I took a look at your module and really like your work, thank you. You also inspired me to take a closer look at D2 and I now see there's little point in refactoring our entire D1 app to handle exceptions "properly", because the refactor would be just another kludge. The better course of action appears to be to plan an eventual migration to D2, and use Dancer2::Plugin::LogReport. -----Original Message----- From: Andrew Beverley Sent: Wednesday, January 13, 2016 7:41 AM To: Perl Dancer users mailing list Subject: Re: [dancer-users] Using Dancer::Exception -- searching for best patterns On Tue, 2016-01-12 at 16:32 -0800, Hermann Calabria wrote:
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).
I wrote (with a little help) Dancer2::Plugin::LogReport for a comprehensive and easy way to do this and a bunch of other stuff, whilst keeping code to a minimum. I'm just about to post an article to the mailing list about it. I realise you're using Dancer1, but you might like to look at the techniques involved, or even consider porting it to Dancer1 if it would be of benefit to you.
1. I don’t want to repeat the same catch {} section within every single route (following principles of D.R.Y.),
That's exactly the idea behind the module - I got very bored writing code similar to that in your examples. Andy _______________________________________________ dancer-users mailing list dancer-users@dancer.pm http://lists.preshweb.co.uk/mailman/listinfo/dancer-users
participants (2)
-
Andrew Beverley -
Hermann Calabria