2012-07-06 5 views
16

Ich versuche, einen REST-Webdienst zu erstellen, der JSON für alle Aufrufe zurückgibt. Normalerweise ist dies ziemlich einfach, das tue ich nur so:Wie werden alle Ausnahmen abgefangen, die in der Symfony2-Controlleraktion auftreten können?

return new Response(json_encode($return_object)); 

Meine Frage ist, wie soll ich Ausnahmen in einer globalen Weise abfangen? Ich möchte dies tun, denn wenn irgendwo in meiner Anwendung eine Ausnahme auftritt, möchte ich immer noch eine JSON-Nachricht an den Client zurücksenden, in der im Grunde gesagt wird: "Yo dawg, ich habe gehört, dass Sie Ausnahmen mögen". Mein Gedanke ist, dass die Rückgabe von JSON sowohl in Erfolgs- als auch in Fehlerfällen die Arbeit vereinfachen wird, die ein Client ausführen muss, um meine API zu implementieren.

Bisher das einzige, was ich denken kann, ist jeder Controller-Aktion wie folgt zu schreiben:

public function generateMemeAction($arg1, $arg2) { 
    $return_object = array(); 
    try { 
    // stuff to generate meme here 
    $return_object['status'] = "GREAT SUCCESS!"; 
    } catch (Exception $e) { 
    // epic fail 
    $return_object['status'] = "UnluckyBrianException"; 
    } 
    return new Response(json_encode($return_object)); 
} 

, die alle groß und wunderbar ist, aber das Try-catch-Block wird das gleiche für jede Aktion sein in meiner App, und ich werde jedes Mal albern fühlen, wenn ich um eine Reihe von Copy Pasta bearbeiten muss. Pro Tipps?

Antwort

17

REST-App haben verschiedene Arten von Fehlern. Z.B. Sie können logische Fehler oder Eingabefehler haben (nicht alle Parameter wurden gesendet). Verschiedene Arten von Fehlern sollten mit unterschiedlichen Wegen gehandhabt werden. Der beste Weg für diesen Fall ist die manuelle Behandlung dieser Fehler.

Sie können zu Ihrem Controller spezielle Fehler Methode hinzufügen (und es z. B. in Elternklasse), die Fehlercode + Fehlertext zurückgibt.

Aber wenn Sie die automatische Handhabung verwenden möchten, können Sie Ausnahme-Listener verwenden:

Hier ist ein Beispiel:

use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent; 
use Symfony\Component\HttpFoundation\Response; 

public function onKernelException(GetResponseForExceptionEvent $event) 
{ 
    $exception = $event->getException(); 
    $response = new Response(); 
    // setup the Response object based on the caught exception 
    $event->setResponse($response); 

    // you can alternatively set a new Exception 
    // $exception = new \Exception('Some special exception'); 
    // $event->setException($exception); 
} 
+5

Super! Danke Evgeny, das macht wirklich alles klar. Ein bisschen mehr graben herum und ich fand genau, wie man eine Funktion zu diesem Ereignis anmeldet: http://symfony.com/doc/current/cookbook/service_container/event_listener.html – robertdfrench

+3

Sie können die JSON-Formatierung bedingt auch anwenden, indem Sie die Anfrage untersuchen headers und früh zurück: 'if (! $ event-> getRequest() -> headers-> enthält ('Accept', 'application/json')) return;' – Tamlyn

Verwandte Themen