[Dancer-users] Setting custom 404 routes when you have more than one app / don't emit HTML

Sam Kington sam at illuminated.co.uk
Sun Jul 8 02:54:23 CEST 2012


Hi,

At $WORK we're building an extensive RESTful system, comprised of multiple apps. The error-handling code in Dancer doesn't do what we want - emit JSON or, possibly, XML when no route is matched - and I can't see an easy way of fixing it, short of hacking on the guts of Dancer.

The try block in Dancer::Handler::render_request reads as follows:

        Dancer::Renderer->render_file
        || Dancer::Renderer->render_action
        || Dancer::Renderer->render_autopage
        || Dancer::Renderer->render_error(404);

render_error assumes it's serving up HTML, so that's no use to our purposes; render_file and render_autopage trawl the filesystem looking for likely candidates, which in this case they won't get.

Dancer::Cookbook suggests:

> All you need to do is set up the following route as the last route:
> any qr{.*} => sub {
>     status 'not_found';
>     template 'special_404', { path => request->path };
> };

Unfortunately, looking at the code for Dancer::App::find_route_through_apps, this doesn't work if you have more than one app:

    for my $app (Dancer::App->current, Dancer::App->applications) {
        my $route = $app->find_route($request);
        if ($route) {
            Dancer::App->current($route->app);
            return $route;
        }
        return $route if $route;
    }

First of all, if any individual app implements such an any qr{.*} route, it'll kick in if it's the current app (and it's then even more likely for that route to be hit next time because it's now the current app), or if it was in the list of applications before another app that might have implemented such a route. OK, I thought, I'll add a specific app which I'll name in such a way as it'll always be at the end of the list, maybe starting with Unicode snowman or something. No luck: here's Dancer::App::applications:

> my $_apps = {};
> sub applications { values %$_apps }

Aarrgghh! Perl's effectively-random hash-key ordering!

Any ideas on how to fix this? Maybe add an additional hook for "no application knew about this route; want to circumvent the default error-handling?" ?

Sam
-- 
Website: http://www.illuminated.co.uk/



More information about the Dancer-users mailing list