ruby - ruby 何时/如何使用救援/确保?
问题描述
我有一个类来调用地理位置 api。下面带有 Json 响应的示例 url 是这样的
{ "location": { "lat": 31.0, "lng": 14.0 }, "accuracy": 112.4 }
我想捕获任何错误,例如 503、404 或任何其他可能由请求对象中的错误引起的错误。在红宝石中救援的正确方法是什么。还。如果有任何错误,我可以从确保块返回消息吗?
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 语句。
推荐阅读
- python - 无法导入 BertTokenizer
- sql-server - 基于 Excel Query 从 SQL Server 拉取数据
- python - Salesforce 到 Salesforce 迁移
- angular - 如何在打开之前在模式内设置反应式表单字段?
- discord - 在命令冷却 Discord.py 中使用变量
- android - Android 由于某种原因我在 onPause 和 onDestroyView 之间有延迟
- safari - Safari 13.1.2 无法识别内容安全策略哈希
- laravel - 返回 Post::all(); - Laravel 版本 8
- python - 什么是更好的解决方案,链式任务或直接调用 python 函数?
- algorithm - 为什么安装在虚拟环境中的模块在 bash 中可用而不是空闲?