1

How to add a specific exception in symfony2 routing.

contact:
    path:     /contact
    defaults: { _controller: AcmeDemoBundle:Main:contact }
    condition: "(context.getMethod() in ['GET', 'HEAD'] and request.headers.get('User-Agent') matches '/firefox/i') ?: [exception]"

2 Answers2

0

Whether or not an exception should be thrown is not a routing decision. It's a logical decision and should therefor be placed in your controller.

Remove the condition from your route and set this in your controller instead:

public function contactAction(Request $request)
{
    if (
        !in_array(array('GET', 'HEAD'), $request->getMethod())
        || 1 !== preg_match('/firefox/i', $request->headers->get('User-Agent'))
    ) {
        throw new BadRequestHttpException('Bad request');
    }
}
Oldskool
  • 34,211
  • 7
  • 53
  • 66
  • thank you for your answer, but I want except launches at routing not in the controller. if the condition is false, it returns me 'An Exception was thrown while handling: No route found ', i want to customize the exception to badrequest – Azouz Jribi Dec 28 '15 at 09:46
0

You can use an ExceptionResponseListener to send a custom Response on the exceptions of your need.

// src/Acme/AppBundle/EventListener/ExceptionResponseListener.php
<?php

namespace Acme\AppBundle\EventListener;

use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpKernel\Exception\NotFoundtHttpException;
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;

class ExceptionResponseListener
{
    /**
     * @param GetResponseForExceptionEvent $event
     */
    public function onKernelResponse(GetResponseForExceptionEvent $event)
    {
        $request = $event->getRequest();
        $routeName = $request->get('_route');
        // Check if it's the good route (or namespace ..)
        if ('your_route' !== $routeName) {
            return;
        }
        $exception =  $event->getException();
        $statusCode = 500;
        $message = $exception->getMessage();

        // Choose the Exception you intercept.
        if ($exception instanceof NotFoundHttpException) {
            $statusCode = $exception->getStatusCode();
            $message = $exception->getMessage();
        }

        // Create your own response
        $content = ['error' => $message];
        $response = new JsonResponse($content, $statusCode);

        // Update the event response
        $event->setResponse($response);
    }
}

Then, register it as service :

parameters:
    acme.kernel.listener.exception_listener.class:
        Acme\AppBundle\EventListener\ExceptionResponseListener
services:
    acme.kernel.listener.exception_listener:
        class: %acme.kernel.listener.exception_listener.class%
        tags:
            - {name: kernel.event_listener, event: kernel.exception, method: onKernelResponse}

Like this you can send your own. Documentation here : http://symfony.com/doc/current/cookbook/event_dispatcher/event_listener.html

chalasr
  • 12,971
  • 4
  • 40
  • 82
  • Thank you, but '$request->get('_route')' does not work. I try "$request->attributes->get('_route')" does not yet work – Azouz Jribi Dec 29 '15 at 11:08
  • You can check the URI of your request by doing : `$request->getPathInfo();` It seems you have a problem in your implementation or a very old symfony release, this method is working well. See [How to get current route in Symfony2](http://stackoverflow.com/questions/7096546/how-to-get-current-route-in-symfony-2). – chalasr Dec 29 '15 at 11:14
  • 1
    I worked with status exception code instead of 'instanceof NotFoundHttpException' because he always returned false :(. thanks for all – Azouz Jribi Dec 29 '15 at 14:34