lembark has asked for the wisdom of the Perl Monks concerning the following question:

Q: What can I use in a Dancer2 before hook to cause the request being processed to hand back an HTTP error?

Say I have a before hook that will filter out requests which are not worth processing. I would like to short-circuit the request and simply return, say, a 404. I've tried variations on bare return, returning a Dancer2::Core::Error object or the result of calling ->throw on one with no luck. I can abort with a 'die' but that leaves me returning a 500, not a 404 whatever. There is documentation in Dancer2 on handling errors generated by Dancer2 itself, but I cannot find anything that describes how to raise an error/exception/whatever from the Perl code running in handlers. The simplest example I can think of is a lightweight handler that rejects botched requests based on IP, username, etc, that are blacklisted.

hook before => sub { ... is_bogus_request $request and ... # what??? };

Replies are listed 'Best First'.
Re: How can I have a Dancer2 before hook return an HTTP error?
by Arunbear (Prior) on Jan 25, 2025 at 13:12 UTC
    From looking at the docs (and not tested):
    hook before => sub { if ($some_condition) { send_error("Not allowed", 403); } };
Re: How can I have a Dancer2 before hook return an HTTP error?
by 1nickt (Canon) on Jan 26, 2025 at 12:37 UTC

    Hi,

    First of all, as you may know, you don't need to code anything to get a 404 error response for a path that does not exist.

    use strict; use warnings; use Dancer2; get '/' => sub { return 'Hello, world'; }; dance;
    $ curl localhost:3000/does_not_exist
    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0 +, user-scalable=yes"> <title>Error 404 - Not Found</title> <link rel="stylesheet" href="http://localhost:3000/css/error.css"> </head> <body> <h1>Error 404 - Not Found</h1> <div id="content"> /does_not_exist </div> <div id="footer"> Powered by <a href="http://perldancer.org/">Dancer2</a> 1.1.2 </div> </body> </html>

    To return an error page based on something like an ID that is not allowed, use send_error:

    use strict; use warnings; use Dancer2; get '/hello/:name' => sub { my $name = route_parameters->get('name'); return "Hello, $name"; }; hook before => sub { my $name = route_parameters->get('name'); is_disallowed($name) and send_error("$name is disallowed", 401); }; sub is_disallowed { my $name = shift; return $name eq 'nick' ? 1 : 0; } dance;
    $ curl localhost:3000/hello/lembark
    Hello, lembark
    $ curl localhost:3000/hello/nick
    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0 +, user-scalable=yes"> <title>Error 401 - Unauthorized</title> <link rel="stylesheet" href="http://localhost:3000/css/error.css"> </head> <body> <h1>Error 401 - Unauthorized</h1> <div id="content"> nick is disallowed </div> <div id="footer"> Powered by <a href="http://perldancer.org/">Dancer2</a> 1.1.2 </div> </body> </html>

    See the documentation.

    Hope this helps

    update: included the before hook, d'oh


    The way forward always starts with a minimal test.