Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 538
Kamil P Avatar asked Sep 15 '26 18:09

Kamil P


2 Answers

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!

like image 90
Renato Mefi Avatar answered Sep 17 '26 09:09

Renato Mefi


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>
like image 35
tomazahlin Avatar answered Sep 17 '26 09:09

tomazahlin



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!