[dancer-users] Triggering 404 error from a hook

Warren Young wyml at etr-usa.com
Fri Nov 13 16:28:13 GMT 2015

On Nov 11, 2015, at 6:31 PM, Hermann Calabria <hermann at ivouch.com> wrote:
> is there a way to pass parameters by modifying the request within a hook?

It sounds like you don’t yet know about the Dancer DSL “var” keyword.  It will let you pass a value determined in the “before” hook down to the route handler.

> And just as a reminder, this is D1, and 'forward' does not appear to work within hooks…

I don’t think you want to use “forward” here anyway.  That’s for chaining route handlers, so that the route the client went to is actually handled by some other route, without redirecting the client.  So, /client/lsi could actually be handled by /client/dell, and your users wouldn’t know it.

I did some testing, and if this cryptic “Internal Server Error” you’re getting is just that, three words and nothing else, then never mind my previous comment.  (I thought you were getting the detailed development-mode Dancer error page.)  I see it here, too, but only on D1.  In D2, “forward” from the “before” hook works!

Replace the “get” handler in a “dancer2 -a fwdtest” app’s main module with this:

    hook before => sub {
        if (request->path =~ m{^/client}) {
            forward '/login' if request->path !~ m{/initech};

    get '/' => sub {
        forward '/login';

    get '/login' => sub {
        template 'index';

    get '/client/:client' => sub {
        return join(' ', "I am a client:", param 'client');

This is the sort of scheme I’m recommending.  The “before” hook verifies that the client is one of the known clients, and if so, it redirects/forwards the caller to /login if it isn’t.

The current “forward” code means that if you go to /client/bob, you get the login page (really, the default index page) but the URL in the browser’s Location bar remains /client/bob.  If you change it to a redirect call, the browser loads /login itself, which I think makes more sense; plus, it works on D1.

By the way, I had to move :client underneath /client to avoid a redirect loop here, since a variable at the top level basically matches everything.  You need to give Dancer’s route handler some unique bit to avoid this.

More information about the dancer-users mailing list