2012-07-06 26 views
16

Tôi đang cố gắng xây dựng một dịch vụ web REST trả về JSON cho tất cả các cuộc gọi. Thông thường đây là khá đơn giản, tôi chỉ làm như thế này:Làm thế nào để nắm bắt tất cả các ngoại lệ có thể phát sinh trong hoạt động của bộ điều khiển Symfony2?

return new Response(json_encode($return_object)); 

Câu hỏi của tôi là, làm thế nào tôi nên chặn trường hợp ngoại lệ trong một cách toàn cầu? Tôi muốn làm điều này, bởi vì nếu một ngoại lệ xảy ra ở bất cứ nơi nào trong ứng dụng của tôi, tôi vẫn muốn trả lại một tin nhắn JSON cho khách hàng nói về cơ bản "Yo dawg, tôi nghe nói bạn thích ngoại lệ". Suy nghĩ của tôi là việc trả về JSON trong cả hai trường hợp thành công và thất bại sẽ đơn giản hóa công việc mà bất kỳ khách hàng nào cần làm để triển khai API của tôi.

Cho đến nay, điều duy nhất tôi có thể nghĩ đến là viết mỗi hành động điều khiển như thế này:

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

Đó là tất cả tuyệt vời và tuyệt vời, nhưng điều đó khối try-catch sẽ giống nhau cho mọi hành động trong ứng dụng của tôi và tôi sẽ cảm thấy ngớ ngẩn mỗi lần tôi phải chỉnh sửa một loạt mì ống sao chép. Mẹo chuyên nghiệp?

Trả lời

17

Ứng dụng REST có loại lỗi khác nhau. Ví dụ. bạn có thể có lỗi logic hoặc lỗi đầu vào (không phải tất cả các thông số đều được gửi). Các loại lỗi khác nhau phải được xử lý bằng các cách khác nhau. Cách tốt nhất cho trường hợp đó là xử lý thủ công các lỗi này.

Bạn có thể thêm vào phương pháp lỗi đặc biệt của Bộ điều khiển (và đặt nó vào ví dụ: trong lớp cha) sẽ trả về mã lỗi + văn bản lỗi.

Nhưng nếu bạn muốn sử dụng xử lý tự động, bạn có thể sử dụng ngoại lệ nghe:

Đây là một mẫu:

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

Tuyệt vời! Cảm ơn Evgeny, điều đó thực sự làm rõ mọi thứ. Tìm hiểu thêm một chút và tôi đã tìm chính xác cách đăng ký một hàm cho sự kiện đó: http://symfony.com/doc/current/cookbook/service_container/event_listener.html – robertdfrench

+3

Bạn cũng có thể áp dụng định dạng JSON theo điều kiện bằng cách kiểm tra yêu cầu tiêu đề và trả về sớm: 'if (! $ event-> getRequest() -> headers-> contains ('Accept', 'application/json')) return;' – Tamlyn

Các vấn đề liên quan