2012-07-06 22 views
16

Estoy intentando crear un servicio web REST que devuelva JSON para todas las llamadas. Normalmente esto es bastante sencillo, sólo lo hago de esta manera:¿Cómo atrapar todas las excepciones que podrían surgir en la acción del controlador Symfony2?

return new Response(json_encode($return_object)); 

Mi pregunta es, ¿cómo debería interceptar excepciones en forma global? Quiero hacer esto, porque si ocurre una excepción en alguna parte de mi aplicación, aún me gustaría devolverle un mensaje JSON al cliente diciendo básicamente "Hola, escuché que te gustan las excepciones". Mi opinión es que devolver JSON en casos de éxito y fracaso simplificará el trabajo que cualquier cliente debe hacer para implementar mi API.

Hasta ahora, lo único que puedo pensar es escribir cada acción del controlador de esta manera:

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

que es todo lo grande y maravilloso, pero ese bloque try-catch será el mismo para cada acción en mi aplicación, y me sentiré tonto cada vez que tenga que editar un montón de pasta de copia. Consejos profesionales?

Respuesta

17

La aplicación REST tiene diferentes tipos de errores. P.ej. puede tener errores lógicos o errores de entrada (no se enviaron todos los parámetros). Se deben manejar diferentes tipos de errores usando formas diferentes. La mejor manera para ese caso es el manejo manual de estos errores.

Puede agregar a su controlador método de error especial (y ponerlo, por ejemplo, en la clase principal) que devolverá el código de error + texto de error.

Pero si desea utilizar la administración automática se puede utilizar de escucha de excepciones:

Este es un ejemplo:

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

¡Impresionante! Gracias Evgeny, eso realmente aclara las cosas. Investigué un poco más y encontré exactamente cómo suscribir una función a ese evento: http://symfony.com/doc/current/cookbook/service_container/event_listener.html – robertdfrench

+3

También puede aplicar el formato JSON condicionalmente inspeccionando la solicitud encabezados y regresar temprano: 'if (! $ event-> getRequest() -> headers-> contains ('Accept', 'application/json')) return;' – Tamlyn

Cuestiones relacionadas