How do I redirect in a class sub-classing the EventSubscriber class? I want to redirect to a specific URL in an EventSubscriber class instead of showing the Page not found page. I followed Symfony2 redirect for event listener? but the redirect goes to the home.

This is the code I am using.

use Drupal\Core\Url;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpKernel\KernelEvents;

class PageNotFound implements EventSubscriberInterface {
  public function pageNotFound(GetResponseEvent $event) {
    $request = $event-&gt;getRequest();
    $id = '1234';
    $scheme_and_http_host = $request-&gt;getSchemeAndHttpHost();
    $url = Url::fromRoute('myroute', ['id' =&gt; $id])-&gt;toString(); // this url exist (checked)

    $response = new RedirectResponse($scheme_and_http_host . $url, Response::HTTP_MOVED_PERMANENTLY);
    $event-&gt;setResponse($response);
  }

  /**
   * {@inheritdoc}
   */
  public static function getSubscribedEvents() {
    $events[KernelEvents::REQUEST][] = ['pageNotFound'];
    return $events;
  }
}


mymodule.services.yml

services:
  mymodule.page_not_found:
    class: Drupal\mymodule\EventListener\PageNotFound
    tags:
      - {name: event_subscriber}


How do I redirect users from an EventSubscriber class?
To catch a 404 exception you need to subscribe to a KernelEvents::EXCEPTION event. As there is already a base class for html exceptions you don't need to code this yourself. You can simply put the code in an on404() method of a class that extends HttpExceptionSubscriberBase:


  Utility base class for exception subscribers.
  
  A subscriber may extend this class and implement getHandledFormats()
  to indicate which request formats it will respond to. Then implement
  an on*() method for any error code (HTTP response code) that should be
  handled. For example, to handle 404 Not Found messages add a method:
  
  public function on404(GetResponseForExceptionEvent $event) {}
  
  That method should then call $event->setResponse() to set the response
  object for the exception. Alternatively, it may opt not to do so and
  then other listeners will have the opportunity to handle the
  exception.