Redirect from within controller always goes to home page
-
21-02-2021 - |
Question
I have a custom module named rsc
.
My Default 404 (not found) page
is set to /page-not-found
in Basic site settings
.
My rsc.routing.yml file contains
rsc.pageNotFound:
path: '/page-not-found'
defaults:
_controller: 'Drupal\rsc\Controller\rscController::pageNotFound'
_title: ''
requirements:
_permission: 'access content'
My rscController.php file contains:
class rscController extends ControllerBase
{
public function pageNotFound()
{
$path = '/test-page'; // Just for testing
if (($url = \Drupal::service('path.validator')->getUrlIfValid($path))) {
$route = $url->getRouteName();
$param = $url->getRouteParameters();
error_log("route=$route param=" . print_r($param, true));
return $this->redirect($route, $param);
}
else {
return
[
'#markup' => 'No such page'
];
}
}
}
/test-page
is the alias for /node/125
.
If I type mywebsite.com/junk
in the address bar (to force the not found page to be invoked) and press Enter, I am always redirected to the home page, even though the error log contains the result
route=entity.node.canonical param=Array ( [node] => 125 )
What am I doing wrong? Why doesn't $this->redirect() take me to the node?
Solution
When you call a controller as error page via the basic site settings this is not the controller of the main request, this controller is executed in a subrequest to get a themed output of the otherwise simple text message you see for non 4xx exceptions like a 500 error.
Better place the redirect in the main request, before the rendering of the exception is delegated to a subrequest by CustomPageExceptionHtmlSubscriber. You can use the default priority 0, because the core exception handler has -50.
@MarshallMorrise has posted the working code at https://drupal.stackexchange.com/a/290659/47547