2014-05-06 78 views
2

我正在嘗試將一個Grape API以json格式應答到它的所有動詞。問題是,我無法讓它回答json格式的路由錯誤。我什至不能拯救ActionController :: RoutingError。Rails 4 Grape API ActionController :: RoutingError

我已閱讀此鏈接https://github.com/intridea/grape/pull/342,我已將cascade指令設置爲false,但API僅以純文本回答「未找到」。

$ curl -X GET http://localhost:3000/api/wrong_uri 
Not Found 

有詳細選項:

$ curl -X GET http://localhost:3000/api/wrong_uri -v 
* About to connect() to localhost port 3000 (#0) 
* Trying 127.0.0.1... connected 
> GET /api/wrong_uri HTTP/1.1 
> User-Agent: curl/7.22.0 (i686-pc-linux-gnu) libcurl/7.22.0 OpenSSL/1.0.1 zlib/1.2.3.4 libidn/1.23 librtmp/2.3 
> Host: localhost:3000 
> Accept: */* 
> 
< HTTP/1.1 404 Not Found 
< Content-Type: text/html 
< Cache-Control: no-cache 
< X-Request-Id: 3cc74a78-3295-4c1f-b989-66d6fac50e5c 
< X-Runtime: 0.002980 
< Server: WEBrick/1.3.1 (Ruby/2.1.1/2014-02-24) 
< Date: Tue, 06 May 2014 05:46:33 GMT 
< Content-Length: 9 
< Connection: Keep-Alive 
< 
* Connection #0 to host localhost left intact 
* Closing connection #0 
Not Found 

我的葡萄文件/app/api/api.rb

module API 
    class Base < Grape::API 
    format :json 
    default_error_formatter :json 
    cascade false 

    rescue_from CanCan::AccessDenied do |e| 
     Rack::Response.new({ error: "Forbidden", detail: "Access denied", status: '403' }.to_json, 403).finish 
    end 

    # it doesn't catch ActionController::RoutingError 
    # rescue_from :all do |e| 
    # error_response({ message: "rescued from #{e.class.name}" }) 
    # end 

    helpers ApiHelpers 

    mount API::Auth 
    mount API::V2 
    mount API::V1 
    end 
end 

回答

4

通過指定cascade false你說葡萄應該被允許處理HTTP沒有Rails干擾的錯誤。因此,如果請求的API的掛載點下方存在不匹配的URI,則不會生成ActionController::RoutingError(這種已由Rails完成),而是逐字返回來自Grape默認「不匹配路由」處理程序的輸出。有些無益的是,即使已指定format :json,此處理程序也會生成一個普通的「Not Found」消息,這就是您所看到的行爲。

解決方案是提供您自己的匹配器,以捕獲您的V1V2模塊中指定的路線以外的路線。嘗試添加該代碼API::Base下三個mount聲明:

# Generate a properly formatted 404 error for all unmatched routes except '/' 
route :any, '*path' do 
    error!({ error: 'Not Found', 
      detail: "No such route '#{request.path}'", 
      status: '404' }, 
     404) 
end 

# Generate a properly formatted 404 error for '/' 
route :any do 
    error!({ error: 'Not Found', 
      detail: "No such route '#{request.path}'", 
      status: '404' }, 
     404) 
end 

當然你要編輯每個route塊體,以滿足您的需求。

由於某些原因,兩個街區似乎都需要捕捉所有不匹配的路線;這是Grape匹配器語法或我理解的限制。

相關問題