[dancer-users] Using Dancer::Exception -- searching for best patterns

Hermann Calabria hermann at ivouch.com
Wed Jan 13 00:32:19 GMT 2016


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;

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.preshweb.co.uk/pipermail/dancer-users/attachments/20160112/85b3d24e/attachment.html>


More information about the dancer-users mailing list