4

I am wanting to not have perl dancers default 404 "Sorry, this is the void." response come up when ever a matching route cannot be found. I also need to do some other task such as error logging when ever this happens.

Here is dancers documentation i followed on creating a default route. https://metacpan.org/pod/Dancer2::Cookbook#Default-Route

This is what i have at the bottom of my main routes file

any qr{.*} => sub {
    status 404;
    template 'test_error_template', { path => request->path };
};

The problem is i still keep getting the default dancer 404 message if an invalid route is requested. Somehow this route is not being picked up.

This is what comes up in development.log if i try going to a non existing route

[server:5931] core @2020-01-22 10:31:55> looking for get /non_existing_route in /usr/share/perl5/vendor_perl/Dancer2/Core/App.pm l. 36
[server:5931] core @2020-01-22 10:31:55> Entering hook core.error.init in (eval 230) l. 1
[server:5931] core @2020-01-22 10:31:55> Entering hook core.error.before in (eval 230) l. 1
[server:5931] core @2020-01-22 10:31:55> Entering hook core.error.after in (eval 230) l. 1

Can anyone help? I do have more than one routes files, could this be part of the issue?

Thanks

jeffez
  • 185
  • 1
  • 12
  • What other routes do you have? Is there a different catch-all as well? Or have you set an error template in the config file? – simbabque Jan 21 '20 at 10:27
  • Did you restart your app after making the change? Did you create the `test_error_template.tt` in your `views/` directory? Did you set `show_errors` to `0` in your environment config file? Try unsetting it. Look at the app's log to see if something else is trying to respond to your request before the catch-all gets to it. You should probably show us all the code so we can help you properly. – simbabque Jan 21 '20 at 14:46
  • @simbabque There are allot of other routes but i checked through and made sure there wasn't any other catch all ones. It's a large production system with thousands of lines and other devs have worked on it. No error template file has been set. I could do this but i still need to catch when it happens so i can do some custom logging and other things. – jeffez Jan 21 '20 at 22:30
  • @simbabque in the dev environment i have it re-compiling on every page load to save the need to restart. Yes **test_error_template.tt** in in views/. I haven't checked **show_errors** in the config though, good point. I am happy to provide more code but all of it is too much as the main routes file is over 6000 lines long. – jeffez Jan 21 '20 at 22:41
  • I set **show_errors** to 0 as it was set to 1 in development.yml but it didn't make a difference. It only appears to affect what happens when 5xx error happens. The app log didn't seem to reveal much but ill put the output in my op. – jeffez Jan 21 '20 at 23:36
  • Is your hook getting called at all? (Put a `warn` or something in it) – ikegami Jan 22 '20 at 03:04
  • 2
    @ikegami yeah the hook isn't being called at all. I did discover something though. So at the top i have ```prefix '/u/:user';``` and if i removed it, the default route worked. Sorry I know that if i posted all my code someone would have seen this but there's allot to trim down and i wanted to keep my OP clean and straight to the point. So basically the default route sample from the documentation works on the assumption there is no url prefix. I just need to figure out how to modify it so it will catch everything. – jeffez Jan 22 '20 at 05:57
  • Well, you could post that as an answer. And if you need to do so, post a new question about your new problem :) – ikegami Jan 22 '20 at 05:58
  • (No experience with Dancer here) – ikegami Jan 22 '20 at 06:01
  • Hopefully ill figure it out and can post a complete answer otherwise yeah i will just post that as the answer. – jeffez Jan 22 '20 at 06:06
  • Some of my earlier questions came straight from a Dancer2 core developer I just happened to be talking to at the time, but he doesn't have enough rep to comment. You want `show_errors` to either not be set or be `1`. Setting it to `0` turns off showing errors. – simbabque Jan 22 '20 at 09:05
  • It looks like the problem is when you have prefix set such as say ```prefix /myprefix```, then the default route wont get triggered unless you include the url prefix first. Eg ```/myprefix/invalid_route``` will call the default route but just calling ```/invalid_route``` will not. Is there a way around this or maybe this is just dancer by design? – jeffez Jan 22 '20 at 22:28
  • I understand what i am trying to do is unusual. It's because the front end of a production system is being refactored and prefixing all urls (there's allot of them) so we want to catch any that may get missed. – jeffez Jan 22 '20 at 22:32

1 Answers1

2

So in my case the problem was having a prefix set in the routes file. The default route wouldn't get triggered unless i included the prefix in the url. Eg /myprefix/invalid_route would call the default route but just calling /invalid_route wouldn't, resulting in the 404 error. I have not completely come up with a work around as yet but this does at least answer my original question.

Edit:

Solved it. I created a new route file default.pm that contains only the default route with prefix '/' and put it last in app.psgi. This way it is reached only when all else fails.

app.psgi

#!/usr/bin/env perl
use strict;
use warnings;

use main_routes;
use default;
myapp->to_app;

default.pm

package default;

prefix '/';

any qr{.*} => sub {
    #log and do other stuff here
    return 'my default route';
};

true;
jeffez
  • 185
  • 1
  • 12