Rails 4 Grape API ActionController :: RoutingError

时间:2014-05-06 05:52:14

标签: api ruby-on-rails-4 grape

我正在尝试以json格式回复所有动词的Grape API。问题是我无法以json格式回答路由错误。我甚至无法拯救ActionController :: RoutingError。

我已阅读此链接https://github.com/intridea/grape/pull/342并且我已将cascade指令设为false,但API仅回答" Not Found"用纯文本。

$ 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

1 个答案:

答案 0 :(得分:5)

通过指定cascade false,您应该允许Grape处理HTTP错误而不受Rails的干扰。因此,当请求API的挂载点下方不匹配的URI时,不会生成ActionController::RoutingError(此 已由Rails完成),而是来自Grape&#39的输出; s默认&#34;不匹配的路线&#34;处理程序逐字返回。有点无益,这个处理程序生成一个简单的&#34; Not Found&#34;即使指定了format :json,也会发出消息,这就是您正在看到的行为。

解决方案是提供您自己的匹配器来捕获除V1V2模块中指定的路径之外的路由。尝试将此代码添加到{/ 1}} 下面的三个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 块的正文以满足您的需求。

出于某种原因,两个街区似乎都是必要的,以捕捉所有不匹配的路线;这是Grape的匹配语法或我理解的限制。