How to set default if presenter not found

+
0
-

Currently my route list looks like this:
code

<?php
final class RouterFactory
{
        use Nette\StaticClass;

        public static function createRouter(): RouteList
        {
                $router = new RouteList;
                $router->addRoute('/', 'Default:Default:default');
                $router->addRoute('[<module>[/<presenter>[/<action>[/<id>]]]]', 'Default:default');
                return $router;
        }
}

?>

If a non-existent address is entered, eg: http://example.com/foo a 404 of generated with the error:

Nette\Application\BadRequestException #404
Cannot load presenter 'Foo:Default', class 'App\FooModule\Presenters\DefaultPresenter' was not found

How can I add a route, which sends all 404 errors to the default presenter, or even a NotfoundPresenter?
eg: http://example.com/foo would be forwarded to http://example.com

Last edited by kevin.waterson@gmail.com (2019-11-14 05:04)

David Grudl
Nette Core | 8135
+
+2
-

Define Error-presenter in config, see doc.

+
0
-

I have read the docs, but my path is different: eg:
app/ErrorModule/presenters/DefaultPresenter

When I use this mask:

application:
        errorPresenter: Error
        mapping:
                *: App\ErrorModule\Presenters\*Presenter

I get an error:
Cannot load presenter ‘Foo:Default’, class ‘App\ErrorModule\Presenters\FooModule\DefaultPresenter’ was not found.

If I change *Presenter to Presenter, the error:
Invalid mapping mask ‘App\ErrorModule\Presenters\Presenter’

What mapping do I need to catch the errors?

jiri.pudil
Nette Blogger | 1028
+
0
-

The errorPresenter is the name of the error presenter in Nette notation, so if you have it in a module, you have to specify it:

application:
	errorPresenter: Error:Default

Mapping is then used to translate this Nette notation into a class name. If all your modules and presenters follow the same rules, you can use the asterisk mapping, otherwise you can specify different mapping per module on top of the asterisk. (doc)

+
0
-

Thanks Jiri, I have tried this, and the error persists for non-existant modules

Nette\Application\BadRequestException #404
Cannot load presenter 'Foo:Default', class 'App\FooModule\Presenters\DefaultPresenter' was not found.

My common.neon file looks like this:

parameters:


application:
        errorPresenter: Error:Default
        mapping:
                *: App\*Module\Presenters\*Presenter


session:
        expiration: 14 days


services:
        router: App\Router\RouterFactory::createRouter

I have even tried
Error:Default
ErrorModule:Default
Error:Default:Default

If I change the mapping to the below,

parameters:


application:
        errorPresenter: Error:Default
        mapping:
                Error: App\ErrorModule\Presenters\Default
                *: App\*Module\Presenters\*Presenter


session:
        expiration: 14 days


services:
        router: App\Router\RouterFactory::createRouter

I then get an error:

Nette\InvalidStateException
Invalid mapping mask 'App\ErrorModule\Presenters\Default'
jiri.pudil
Nette Blogger | 1028
+
+1
-

Oh, I see! The exception (Nette\Application\BadRequestException #404) is actually correct, the problem is that it is not caught. And that's also expected: whether it's caught or not is determined by the catchExceptions configuration option which defaults to !debugMode, i.e. exceptions are not caught by default in the development environment, while on production they are caught and passed on to the error presenter.

To be able to test the error presenter behaviour, you can explicitly enable catchExceptions for the development environment, e.g. in config.local.neon:

application:
	catchExceptions: true