2012-07-06 7 views
16

Sto cercando di creare un servizio Web REST che restituisca JSON per tutte le chiamate. Normalmente questo è piuttosto semplice, solo che in questo modo:Come catturare tutte le eccezioni che potrebbero sorgere nell'azione del controller Symfony2?

return new Response(json_encode($return_object)); 

La mia domanda è, come devo intercettare le eccezioni in modo globale? Voglio farlo, perché se accade un'eccezione ovunque nella mia applicazione, mi piacerebbe comunque restituire un messaggio JSON al client dicendo in pratica "Yo dawg, ho sentito che ti piacciono le eccezioni". Penso che restituire JSON nei casi di successo e fallimento semplificherà il lavoro che ogni cliente deve fare per implementare la mia API.

Finora, l'unica cosa che mi viene in mente è quello di scrivere ogni azione di controllo in questo modo:

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)); 
} 

che è tutto grande e meraviglioso, ma questo blocco try-catch sarà lo stesso per ogni azione nella mia app, e mi sentirò sciocco ogni volta che dovrò modificare un mucchio di pasta per copiare. Consigli Pro?

risposta

17

L'app REST presenta diversi tipi di errori. Per esempio. puoi avere errori logici o errori di input (non tutti i parametri sono stati inviati). Diversi tipi di errori dovrebbero essere gestiti utilizzando diversi modi. Il modo migliore per questo caso è la gestione manuale di questi errori.

È possibile aggiungere al proprio metodo di errore speciale del controller (e inserirlo, ad esempio, nella classe padre) che restituirà il codice di errore + il testo di errore.

Ma se si desidera utilizzare la gestione automatica è possibile utilizzare Eccezione ascoltatore:

Ecco un esempio:

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

Fantastico! Grazie Evgeny, questo chiarisce davvero le cose. Un po 'più di scavo e ho trovato esattamente come iscrivere una funzione a quell'evento: http://symfony.com/doc/current/cookbook/service_container/event_listener.html – robertdfrench

+3

Puoi anche applicare la formattazione JSON condizionalmente ispezionando la richiesta intestazioni e ritorno anticipato: 'if (! $ event-> getRequest() -> headers-> contains ('Accept', 'application/json')) return;' – Tamlyn

Problemi correlati