R
R
Radarchik2017-12-15 20:34:50
symfony
Radarchik, 2017-12-15 20:34:50

How to make a redirect in your exception handler?

/*
When I go to the /login_form page, the Twig_Error_Runtime exception overrides my AlreadyLoginException, how can I suppress the Twig_Error_Runtime?
*/
EDIT: How to redirect in your exception handler? the exception is thrown from the controller which is rendered in the twig template. In the dev environment, the redirect happens, in the prod environment, the controller is simply not rendered in the template.
Code just as an example:
Symfony 3.4

namespace AppBundle\Controller;

use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use AppBundle\Exception\AlreadyLoginException;

class DefaultController extends Controller
{
    /**
     * @Route("/", name="homepage")
     */
    public function indexAction(Request $request)
    {
        return $this->render('default/index.html.twig', [
            'base_dir' => realpath($this->getParameter('kernel.project_dir')).DIRECTORY_SEPARATOR,
        ]);
    }
    
    /**
     * @Route("/login", name="login")
     */
    public function loginAction(Request $request)
    {
        if ($this->getUser()) {
          throw new AlreadyLoginException('This user does not have access to this section.');
        }

        return $this->render('default/login.html.twig', []);
    }
    
    /**
     * @Route("/login_form", name="login_form")
     */
    public function loginFormAction(Request $request)
    {
        return $this->render('default/login_form.html.twig', []);
    }
}

namespace AppBundle\EventListener;

use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
use Symfony\Component\HttpFoundation\RedirectResponse;
use AppBundle\Exception\AlreadyLoginException;
use Symfony\Component\Routing\RouterInterface;

class AlreadyLoginExceptionListener
{
    private $router;
  
    public function __construct(RouterInterface $router)
    {
        $this->router = $router;
    }
    
    public function onKernelException(GetResponseForExceptionEvent $event)
    {
        if ((!$event->getException()->getPrevious() instanceof AlreadyLoginException)
              && (!$event->getException() instanceof AlreadyLoginException)) {
            return;
        } //@voronkovich thx 

        $response = new RedirectResponse($this->router->generate('homepage'));
        $event->setResponse($response);
    }
    
}

services:
    kernel.listener.alreadyloginexception:
        class: AppBundle\EventListener\AlreadyLoginExceptionListener
        arguments:
            - "@router"
        tags:
            - { name: kernel.event_listener, event: kernel.exception }

{# login_form.html.twig #}
{{ render(controller('AppBundle:Default:login')) }}

Answer the question

In order to leave comments, you need to log in

2 answer(s)
V
voronkovich, 2017-12-15
@voronkovich

I guess Twig wraps the exceptions that are raised. To get an instance of the original exception, use the getPrevious method : php.net/manual/en/class.exception.php .

if (!$event->getException()->getPrevious() instanceof AlreadyLoginException) {
    return;
}

D
Denis, 2017-12-16
@prototype_denis

At you a task not to start up the authenticated yuzverya?
Write the Security annotation on an anonymous user or write in security.yml that only anonymous users can enter the page.
Better yet, redirect from this page.
The whole solution is at least 1 line in the configuration or 2 in a specific controller.
PS.
An authenticated user entering a page for an anonymous user should not be an exception in your business logic. The reverse is yes. But the framework does it for you, redirecting the user to the login_path

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question