繁体   English   中英

ruby 何时/如何使用救援/确保?

[英]ruby when/how to use rescue/ensure?

我有一个类来调用地理位置 api。 下面的示例 URL 与 Json 响应类似

{ "location": { "lat": 31.0, "lng": 14.0 }, "accuracy": 112.4 }

我想捕获任何错误,例如 503、404 或可能由请求对象中的错误引起的任何其他错误。 在 ruby​​ 中进行救援的正确方法是什么。 还。 如果有任何错误,我可以从 ensure 块中返回一条消息吗?

def findlocation
  begin
    location = httparty.get("https://www.googleapis.com/geolocation/v1/geolocate?key=#{API_KEY}")
  rescue 
    # do something after catching error
  ensure
    return { "message" : "unable to find location" }
  end 
end

一般来说,异常应该用于异常事件。 不是常规的申请流程。

捕获异常时总是具体的,并且只拯救您知道如何处理的异常。

begin 
  pats "hello world"
rescue 
  nil
end

这个例子显示了你问题中的代码中的一个严重缺陷——你创建了一个黑洞,它吞噬了 NoMethodError,它会告诉我们代码中有一个错字。 这使得调试极其困难。 这种反模式被称为神奇宝贝异常处理(Gotta catch em' all)。

ensure只是确保代码运行,无论代码是否引发异常。 例如,它用于保证该方法关闭它已打开或回滚事务的文件处理程序。 它是一个非常大的锤子,应该非常谨慎地使用。

当响应代码是“错误”代码时,HTTParty 实际上不会引发异常 - 因为它不是异常事件。 它是处理 HTTP 请求时正常应用程序流程的一部分。 狗屎发生了。 如果您根本无法访问服务器或什至无法访问网络,则 HTTParty 会引发异常。 这些都是特殊事件。

class GeolocationClient
  include HTTParty 
  base_uri "https://www.googleapis.com/geolocation/v1"
  format :json
  attr_accessor :options

  def initialize(api_key:)
    @options = {
      api_key: api_key
    }
  end

  def geolocate
    begin 
      response = self.class.get("/geolocate", options)
      if response.successful?
        response 
      else
        logger.info("Geolocation API call was unsuccessful. Status code: #{response.code}")
        handle_unsuccessful_request
      end
    rescue HTTParty::Error => e 
      logger.warn(e.message)
      handle_unsuccessful_request
    end
  end

  private

  def handle_unsuccessful_request
    { "message" : "unable to find location" }
  end
end

response.successful? 测试响应是否在2xx “快乐范围”内。 如果要分别处理每个代码或代码范围,请使用 switch 语句。

有几种方法可以处理这个问题。 首先,我想假设您正在使用 HTTParty 库。 如果是这种情况,那么您应该将其称为 HTTParty 而不是 httparty。

让我们说你想恢复你可以做的每个错误

response = HTTParty.get("https://www.googleapis.com/geolocation/v1/geolocate?key=#{API_KEY}")

case response.code
  when 503
    # do something, Internal Server error
  when 404
    # do something, Page Not found
  when 500...600
    # do something, unexpected error
end

然而,上述情况假设您以某种方式能够与请求的 url 交谈。 如果在任何情况下您都无法与服务器通信并且您想从一般的 HTTParty 错误中解救出来,您可以这样做

def findlocation
  begin
    response = HTTParty.get("https://www.googleapis.com/geolocation/v1/geolocate?key=#{API_KEY}")
  rescue HTTParty::Error => e 
    # Something is wrong 
    puts "#{e.message}"
end

ensure允许您运行一段代码,无论是否发生异常。 因此,如果您想要执行一段代码,而不管您是否能够与 Google API 对话,请将其放入 ensure 块中

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM