Search code examples
phpsymfonybundlesymfony-3.3

Symfony error page only when inside the custom route


I am currently developing a re-usable bundle, wherein I am making additional routes (set inside routing.yml + loaded with Routing Loader mechanism). All start with /admin (yes, this is an admin bundle). I have currently my own 404 page in my web-application (the main one). And I am trying to make that if the user is inside the admin bundle error he will see another error pages.

I made it with my own custom ExceptionListener (inside the custom admin bundle!) as following

  class ExceptionListener
  {
     //...
     public function onKernelException(GetResponseForExceptionEvent $event)
     {
        $exception = $event->getException();
        $response = new Response();

        //...

        $response->setContent($this->templating->render($templateName, [
            'statusCode' => $response->getStatusCode(),
            'page' => $page
        ]));
        $event->setResponse($response);
     }
  }

and in the bundle's services.yml:

 admin.exception_listener:
    class: ....\EventListener\ExceptionListener
    calls:
        - ["setTemplating", ["@templating"]]
        - ["setKernel", ["@kernel"]]
    tags:
       - { name: kernel.event_listener, event: kernel.exception }

Now it works fine, all custom bundle's error pages are shown. But they are being shown everywhere, even in the main application route fails.

How do I separate when to show application error pages and when to show custom-bundles?


Solution

  • I'm going to assume that you want a different 404 page if the user attempts to visit a route that begins with /admin but doesn't exist. You can do that in your onKernelException() method via:

    $request = $event->getRequest();
    
    // check if request starts with /admin
    if (substr($request->getRequestUri(), 0, strlen('/admin')) === '/admin') {
        // load admin 404 template
        $response->setContent(/* ... */);
    } else {
        // load site 404 template
        $response->setContent(/* ... */);
    }
    
    $event->setResponse($response);
    

    I also notice you're not explicitly checking for a 404 page, which you should probably do via:

    if ($exception instanceof NotFoundHttpException) {
        /* set your template response here */
    }