Kamil P
Kamil P

Reputation: 784

Symfony2, FOSRestBundle - catch exceptions

I have Symfony application and I use FOSRestBundle with AngularJS. My Symfony application haven't any views.

I want to show in AngularJS messages about information received from server, with ngToast module.

If I create something or update it it's easy to show. But If server throw some exception? For example Angular client trying get item with wrong ID or this user have no acces to do this action? In this case server will throw exception, but I want to show appropriate message.

Can symfony catch this exception and for example translate it to Response object? For example - if I have no access exception symfony should catch it and make something like this:

return new Response(400, "You don't have permission to acces this route");

and Angular will get:

{
    "code": 400,
    "message": "You don't have permission to acces this route"
}

Is it possible? How should I do it? Maybe I should do it other way.

Upvotes: 3

Views: 819

Answers (2)

Renato Mefi
Renato Mefi

Reputation: 2171

I would suggest to go for more FOSRestBundle approach, which is to configure the Exceptions and if should or not show the messages:

fos_rest:
  exception:
    enabled: true
    codes:
      'Symfony\Component\Routing\Exception\ResourceNotFoundException': HTTP_FORBIDDEN
    messages:
      'Symfony\Component\Routing\Exception\ResourceNotFoundException': true

Lets say you have a custom AccessDeniedException for a certain action, you can create the exception and then put it in the configuration.

<?php
class YouCantSummonUndeadsException extends \LogicException
{
}

Wherever you throw it:

<?php
throw new YouCantSummonUndeadsException('Denied!');

You can configure it:

    codes:
      'My\Custom\YouCantSummonUndeadsException': HTTP_FORBIDDEN
    messages:
      'My\Custom\YouCantSummonUndeadsException': true

And get a result like:

{
    "code": 403,
    "message": "Denied!"
}

I hope this makes it clearer!

Upvotes: 4

tomazahlin
tomazahlin

Reputation: 2167

Yes of course this is possible. I suggest you implement a simple Exception listener. And make all your exception classes extend a BaseException or implement a BaseException, so you will know which exceptions are from "your" code.

class ExceptionListener
{
    public function onKernelException(GetResponseForExceptionEvent $event)
    {
        // You get the exception object from the received event
        $exception = $event->getException();

        // Do your stuff to create the response, for example response status code can be exception code, and exception message can be in the body or serialized in json/xml.

        $event->setResponse($response);

        return;
    }

}

Register it in the container:

<service id="your_app.listener.exception" class="App\ExceptionListener">
    <tag name="kernel.event_listener" event="kernel.exception" method="onKernelException" />
</service>

Upvotes: 2

Related Questions