2012-07-06 14 views
16

Próbuję zbudować usługę sieci Web REST, która zwraca JSON dla wszystkich połączeń. Zwykle jest to bardzo proste, po prostu zrobić tak:Jak wychwycić wszystkie wyjątki, które mogą wystąpić w działaniu kontrolera Symfony2?

return new Response(json_encode($return_object)); 

Moje pytanie jest, w jaki sposób należy przechwytywać wyjątków w globalnej sposób? Chcę to zrobić, ponieważ jeśli w moim zgłoszeniu wystąpi wyjątek, nadal chciałbym zwrócić klientowi wiadomość JSON mówiąc "Yo dawg, słyszałem, że lubisz wyjątki". Uważam, że zwracanie JSON zarówno w przypadkach sukcesów, jak i niepowodzeń uprości pracę, którą każdy klient musi wykonać, aby zaimplementować mój interfejs API.

Dotychczas jedyną rzeczą, którą mogę pomyśleć, to napisać każde działanie kontrolera takiego:

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

Jakie to wszystko wielkie i wspaniałe, ale blok try-catch będą takie same dla każdego działania w mojej aplikacji i będę się czuł głupio za każdym razem, gdy będę musiał edytować wokół kupki makaronu kopii. Pro porady?

Odpowiedz

17

Aplikacja REST ma inny typ błędów. Na przykład. możesz mieć błędy logiczne lub błędy wejściowe (nie wszystkie parametry zostały wysłane). Różne typy błędów powinny być obsługiwane przy użyciu różnych metod. Najlepszym sposobem w tym przypadku jest ręczna obsługa tych błędów.

Możesz dodać do swojej specjalnej metody błędu Kontrolera (i umieścić ją np. W klasie nadrzędnej), która zwróci kod błędu + tekst błędu.

Ale jeśli chcesz korzystać z automatyczną obsługę można użyć Exception słuchacza:

Oto przykład:

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

Awesome! Dzięki Evgeny, to naprawdę oczyszcza sprawy. Trochę więcej pracowałem i znalazłem dokładnie, jak zasubskrybować funkcję do tego wydarzenia: http://symfony.com/doc/current/cookbook/service_container/event_listener.html – robertdfrench

+3

Możesz także zastosować warunkowe formatowanie JSON, sprawdzając żądanie nagłówki i powracające wcześnie: 'if (! $ event-> getRequest() -> nagłówki-> zawiera ('Accept', 'application/json')) return;' – Tamlyn

Powiązane problemy