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;