Dancer: Send 404 Not Found manually

If a user arrives to a URL path that is not associated with anything then Dancer will automatically return a 404 Not Found page. What if we have a catch-all route as in the previous example, where one part of the URL path is the ID of a user. What if then someone tries to access a page that does not belong to any user? Ideally the application would return a 404 Not Found page this time as well, but Dancer cannot automatically understand which ID is valid and when to send a 404 Not found page.

We have to send it manually. For this, before sending back the page we first call status 'not_found'; to tell Dancer to set the HTTP return status to 404. Then we can send back any HTML (or plain text). It will be displayed but the browser, or whatever client the user uses will be also told the status code is 404.

package App;
use Dancer2;

get '/' => sub {
    return q{
        <a href="/user/1">One</a><br>
        <a href="/user/2">Two</a><br>
        <a href="/user/foobar">foobar</a><br>
        <a href="/user">user</a><br>
        <a href="/user/">user/</a><br>
        <a href="/user/a/b">a/b</a><br>
        <a href="/user/-1">-1</a><br>
        <a href="/user/1.1">1.1</a><br>

get '/user/:id' => sub {
    my $id = route_parameters->get('id');
    if (not valid_id($id)) {
        status 'not_found';
        return 'No such ID';
    return $id;


sub valid_id {
    my ($id) = @_;

    # Database lookup
    return if $id <= 0;
    return if $id >= 42;
    return 1;