For a client's website I have these URLs:
library
library/{category}
I have a ParamConverter to verify that {category} is correct and return the taxonomy term. And each URL requires a "view library" permission which anonymous doesn't have.
The client's requirements are that 404 errors redirect the user to the login page if not logged in.
I created a RedirectOn404Subscriber
event subscriber to handle the 404 and redirect as needed. (I have tested it with a logged-in user and can redirect using this.)
When not logged in the redirection works fine for any obvious URL error:
example.com/xxxxx
And works for these:
example.com/library
example.com/library/valid-category
But this does not redirect:
example.com/library/invalid-category
It generates the 404 error but does not hit the redirect code.
It's as if it's not executing the ParamConverter when it's wrong - but it can't know that until it's executed the code...
Clearing caches just prior to a test does not alter the behaviour.
UPDATED TO INCLUDE CODE
404 redirect...
/**
* Prevents this being called when it's not an HTML request.
*
* @return array
*/
protected function getHandledFormats() {
return ['html'];
}
/**
* Specifies the priority of all listeners in this class.
*
* The default priority is 1, which is very low. To have listeners that have
* a "first attempt" at handling exceptions return a higher priority.
*
* @return int
* The event priority of this subscriber.
*/
protected static function getPriority() {
return 750;
}
/**
*
*
* @param GetResponseForExceptionEvent $event
*/
public function on404(GetResponseForExceptionEvent $event) {
if ($this->currentUser->isAnonymous()) {
// Any 404 when not logged in, return to front page.
$route_name = '<front>';
}
else {
// Any 404 when logged in, return to base page for user.
#$route_name = 'user.page';
return;
}
$query = $event->getRequest()->query->all();
$redirect_uri = Url::fromRoute($route_name, [], ['query' => $query]);
$returnResponse = new RedirectResponse($redirect_uri->toString());
$event->setResponse($returnResponse);
}
403 redirect...
public function on403(GetResponseForExceptionEvent $event) {
$request = $event->getRequest();
$is_anonymous = $this->currentUser->isAnonymous();
$route_name = $request->attributes->get('_route');
$is_not_login = $route_name != 'user.login';
if ($is_anonymous) {
if ($is_not_login) {
$query = $request->query->all();
$redirect_uri = Url::fromRoute('<front>', [], ['query' => $query])->toString();
}
else {
// Do not redirect, this is an anonymous login.
$redirect_uri = NULL;
}
}
else {
// Any 403 when logged in, return to base page for user.
#$redirect_uri = Url::fromRoute('user.page')->toString();
return;
}
if (!empty($redirect_uri)) {
$returnResponse = new RedirectResponse($redirect_uri);
$event->setResponse($returnResponse);
}
}