[dancer-users] http_throw and Dancer2

Andrew Beverley andy at andybev.com
Thu Feb 4 14:05:51 EST 2021


On Thu, 4 Feb 2021 08:44:15 -0500 Paul Clements wrote:
> On Thu, Feb 4, 2021 at 5:34 AM Andrew Beverley <andy at andybev.com> wrote:
> >
> > On Wed, 3 Feb 2021 17:49:05 -0500 Paul Clements wrote:
> > > I've been trying for a while now to figure out the best way to handle
> > > exceptions with Dancer2.
> >
> > Do you mean "expected" or "unexpected" exceptions? I.e. exceptions you
> > use for application flow, or ones that are as a result of internal bugs.
> 
> Sorry, I should have been more clear. I'm developing an API, and I'm
> mostly looking to handle what you call expected exceptions. The PSGI
> HTTPExceptions module seems to be along the lines of what I'm looking
> for.

Thanks for clarifying.

> The idea is to have a single, simple way from anywhere in the codebase
> to return, say, an HTTP 400 error (wrapped in JSON) to the API user.
> Some authentication util methods would probably also like to return a
> 401 or 403 for certain conditions.

I do actually use the aforementioned module for an API too. I define a
custom fatal handler which returns a JSON object based on either the
request URL or requested content-type. E.g.

https://github.com/ctrlo/GADS/blob/e532a06/lib/GADS/API.pm#L32

Examples also in the pod (although just noticed one isn't formatted
properly):

https://metacpan.org/pod/Dancer2::Plugin::LogReport#$obj-%3Efatal_handler()

The idea is that you throw an exception anywhere:

  error __x"Invalid email address: {email}", email => $email

Then it ends up in the fatal_handler to return the custom response

> So, ideally, I'd rather not have anything grab and rethrow exceptions
> as strings (as seems to happen now in a few places in the Dancer2
> codebase). I guess I'm really looking for a way to avoid or circumvent
> what seems to be the default Dancer exception handling behavior.

If you use the plugin, the exceptions will all be objects. You could
also add classes to define response codes. E.g.

  error "You are forbidden to access this resource", _class => "forbidden"

And then in the handler:

  if $msg->inClass('forbidden') ...

Andy


More information about the dancer-users mailing list