需要使用 RestClient 挽救 401 状态码

Need to rescue 401 status code using RestClient

我正在使用 Rails gem 通过 RestClient 向 api 发送请求。我需要挽救 401 错误代码。我在 RestClient 文档中看到了以下内容:

> RestClient.get('http://my-rest-service.com/resource'){ |response,
> request, result, &block|   case response.code   when 200
>     p "It worked !"
>     response   when 423
>     raise SomeCustomExceptionIfYouWant   else
>     response.return!(request, result, &block)   end }

我试图实现类似的案例陈述:

case response.code
 when 200
  JSON.parse(response.body)
 when 401
  raise AuthenicationError, "Unauthorized"
 else
  raise RestClient::ExceptionWithResponse
end

它捕获了 200 个案例,但忽略了 401 个案例并直接进入其他。关于对通过 RestClient 返回的响应引发 401 异常的任何建议?

您使用了错误的 HTTP 代码。未授权实际上是401,而不是410。

我不能告诉你为什么我确定 rest-client 回购可以告诉你 :) ...但是使用 RestClient::Request.new 然后执行带有块的 api 调用为了我。 我认为这可能与 RestClient 内置异常这一事实有关。

request = RestClient::Request.new(
    method: :get,
    url: 'https://my-rest-service.com/resource.json')
response = request.execute {|response| response}
case response.code
  when 200
    puts "Good"
  when 401 
    puts "Bad"
    raise Exception
end

It captures the 200 case fine but ignores the 401 case and goes straight to the else.

我宁愿怀疑它不会去其他地方,实际上;即使你完全去掉 else 子句,你仍然会得到 RestClient::ExceptionWithResponse,因为 that's what RestClient.get does when it gets an error response such as in the 400 or 500 range。来自自述文件:

  • for result codes between 200 and 207, a RestClient::Response will be returned
  • for result codes 301, 302 or 307, the redirection will be followed if the request is a GET or a HEAD
  • for result code 303, the redirection will be followed and the request transformed into a GET
  • for other cases, a RestClient::ExceptionWithResponse holding the Response will be raised; a specific exception class will be thrown for known error codes
  • call .response on the exception to get the server's response

如果您在 rescue 块中捕获来自 Request.execute 的异常,请注意您还可以从异常中获取响应正文,例如:

def request(method, url, params = {})
  resp = RestClient::Request.execute(
    method: method,
    url: url,
    timeout: 30,
    accept: :json,
    payload: params.to_json,
    headers: {
      content_type: :json,
    }
  )
  JSON.parse(resp.body)
rescue => e
  { error: e.message, body: JSON.parse(e.response.body) }               # <-------------
end