ruby – 强大地调用一个flaky API:使用Net :: HTTP进行适当的错误处理

前端之家收集整理的这篇文章主要介绍了ruby – 强大地调用一个flaky API:使用Net :: HTTP进行适当的错误处理前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我把这个整合在一起是一个看似强大的方法调用一个片断的webservice,它提供了超时和偶尔的名称解析或套接错误或者其他的错误.
我以为我会把它放在这里,万一它是有用的,或者更有可能被告知一个更好的方法来做到这一点.
require 'net/http'

retries = 5
begin
  url = URI.parse('http://api.flakywebservice.com')
  http = Net::HTTP.new(url.host,url.port)
  http.read_timeout = 600  # be very patient
  res = nil
  http.start{|http|
    req = Net::HTTP::Post.new(url.path)
    req.set_form_data(params)  # send a hash of the POST parameters
    res = http.request(req)
  }
rescue Exception   # should really list all the possible http exceptions
  sleep 3
  retry if (retries -= 1) > 0
end

# finally,do something with res.body,like JSON.parse(res.body)

这个问题的核心是:
当打电话给这样一个webservice时,我应该寻找什么样的例外?
这是试图收集他们,但似乎有一个比这更好的方法
http://tammersaleh.com/posts/rescuing-net-http-exceptions

解决方法

异常是有意义的,Net :: HTTP为不同类型的情况提供了特殊的例外.所以如果你想以特定的方式处理它们,你可以.

那篇文章说,处理这些特定的例外比处理救援异常更好/更安全,这是非常真实的.但是,拯救异常与救援本身不同,这相当于拯救了StandardError,如果你没有任何理由做任何事情,你通常应该通常执行此操作.

抢救顶级异常将会拯救整个执行堆栈中可能发生的任何事情,包括某些部分的ruby从磁盘或内存中运行,或者有一些模糊的与系统有关的IO问题.

所以,就“拯救什么”而言,如果你改变你的代码去拯救,你通常会更好.你会抓住你想要的所有东西,没有你不想要的东西.然而,在这种特殊情况下,那个家伙的列表中没有一个唯一的例外,它不是StandardError的后代:

def parents(obj)
  ( (obj.superclass ? parents(obj.superclass) : []) << obj)
end

[Timeout::Error,Errno::EINVAL,Errno::ECONNRESET,EOFError,Net::HTTPBadResponse,Net::HTTPHeaderSyntaxError,Net::ProtocolError].inject([]) do |a,c|
  parents(c).include?(StandardError) ? a : a << c
end
# Timeout::Error < Interrupt

parents(Timeout::Error)
# [ Object,Exception < Object,SignalException < Exception,#   Interrupt < SignalException,Timeout::Error < Interrupt ]

所以你可以改变你的代码来拯救StandardError,Timeout :: Error => e,你会涵盖那篇文章中提到的所有案例,而不是你不想覆盖的内容. (=> e不是必需的,但下面更多).

现在,就您处理flakey API的实际技术而言,问题是,您正在处理的API有什么问题?格式不正确的回复?没有回应? HTTP级别的问题还是您要恢复的数据?

也许你还不知道,或者你还不在乎,但你知道重试往往完成工作.在这种情况下,我至少建议记录例外. Hoptoad有一个免费的计划,并有某种东西像Hoptoad.notify(e) – 我不记得如果这是确切的调用.或者您可以使用e.message和e.stacktrace通过电子邮件登录.

猜你在找的Ruby相关文章