2015-03-02 21 views
5

Đầu tiên:nho: Rescue từ JSON không hợp lệ

Tôi đang sử dụng nho để xây dựng API của tôi (Rails 4). Khi ai đó đang gửi một cơ quan JSON không hợp lệ (ví dụ quên ngoái }), các lỗi sau được nâng lên:

ActionDispatch::ParamsParser::ParseError (795: unexpected token at '{"foobar": 1234 

') 

Tôi đã thử nó với nho rescue_from :all tùy chọn, nhưng điều này không hoạt động. Bên trong stacktrace, tôi không thấy đá quý nho tham gia. Có vẻ như rằng lỗi này được ném từ actionpack:

.gems/gems/actionpack-4.1.4/lib/action_dispatch/middleware/params_parser.rb:53:in `rescue in parse_formatted_parameters' 
    .gems/gems/actionpack-4.1.4/lib/action_dispatch/middleware/params_parser.rb:32:in `parse_formatted_parameters' 
    .gems/gems/actionpack-4.1.4/lib/action_dispatch/middleware/params_parser.rb:23:in `call' 

Nhưng điều gì sẽ là cách tốt nhất để đón những sai sót, trở lại một 400: Bad Request lỗi, và bao gồm các unexpected token at '{"foobar": 1234 nhắn bên trong phản ứng json?

Thứ hai:

Tôi cố gắng để kiểm tra điều này với RSpec, nhưng không có bất kỳ may mắn về việc gửi một yêu cầu nguyên với JSON không hợp lệ. Tôi đã thử nó với

post "/my_route", '{some invalid json' 

nhưng điều này không ném lỗi từ trên cao. Tôi nghĩ rằng kể từ Rails 4, tham số thứ hai, được truyền như một chuỗi, được xử lý như cơ thể thô?

+0

Tôi nghĩ bạn nên xem xét tách câu hỏi này thành hai câu hỏi ... –

Trả lời

4

Thật không may ActionDispatch chạy tốt trước nó bao giờ nhận được đến một bộ điều khiển, do đó bạn sẽ không thể làm điều này với Grape (AFAIK).

Chúng tôi cũng gặp sự cố này và đã tìm thấy một số wonderful article từ các nhóm Thoughtbot về chủ đề này.

Sử dụng đá quý Curb để làm cho các cuộc gọi shotty:

require 'curb' 
it 'sends poorly formatted json' do 
    broken_json = %Q|{"notice":{"title":"A sweet title"#{invalid_tokens}}}| 
    resp = Curl.post("http://#{host}:#{port}#{path}", broken_json) 

    expect(resp.response_code).to eq 500 
end 

Thoughtbot khuyên nên viết một lớp trung gian để nắm bắt JSON tương lai phân tích lỗi như thế này:

# in app/middleware/catch_json_parse_errors.rb 
class CatchJsonParseErrors 
    def initialize(app) 
    @app = app 
    end 

    def call(env) 
    begin 
     @app.call(env) 
    rescue ActionDispatch::ParamsParser::ParseError => error 
     if env['HTTP_ACCEPT'] =~ /application\/json/ 
     error_output = "There was a problem in the JSON you submitted: #{error}" 
     return [ 
      400, { "Content-Type" => "application/json" }, 
      [ { status: 400, error: error_output }.to_json ] 
     ] 
     else 
     raise error 
     end 
    end 
    end 
end 
+0

Cảm ơn bạn, tôi sẽ thử! Một câu hỏi nữa: Tôi không có capybara chạy, tôi chỉ sử dụng thông số kỹ thuật rspec 'type:: request'. Làm thế nào tôi có thể tìm ra máy chủ lưu trữ hiện tại (nên là localhost) và cổng? – 23tux

+0

Tôi chỉ cần đặt một hằng số trong 'spec_helper' của bạn cho máy chủ (bằng localhost). – Anthony

+0

Ok, máy chủ lưu trữ là rõ ràng, nhưng những gì về cảng? Có cách nào để tìm hiểu, trên đó cổng rspec đang chạy đường ray? – 23tux

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