Puppet自定义Ruby函数无法捕获HTTP请求异常问题咨询
核心结论
你已经成功捕获了HTTP请求的Errno::ECONNREFUSED异常,最终抛出的报错来自rescue块内的字符串拼接代码,而非原始请求异常未被捕获。
报错原因
- Ruby中执行字符串与其他类型对象的
+拼接操作时,会尝试对非字符串对象做隐式String类型转换,要求对象实现to_str方法。 - 你在irb中使用的是标准Ruby环境,
Errno系列异常默认实现了to_str方法,因此可以正常隐式转换后完成拼接。 - Puppet自定义函数运行在Puppet自带的独立Ruby运行时中,该环境下的
Errno::ECONNREFUSED异常仅实现了to_s方法,没有实现to_str方法,无法完成隐式类型转换,因此抛出了no implicit conversion of Errno::ECONNREFUSED into String的新错误。
修复方案
将rescue块中的字符串拼接代码改为显式转换异常对象为字符串,或者使用Ruby字符串插值(自动调用to_s方法)即可,示例如下:
require "net/http" require "uri" uri = URI("http://db.net:3013/api/nagios/sets.cfg") begin puts "here" res = Net::HTTP.get_response(uri) puts "No here" rescue Errno::ECONNREFUSED => e # 写法1:显式调用to_s puts "http://db.net:3013/api/nagios/sets.cfg " + e.to_s # 写法2:字符串插值,更推荐 # puts "http://db.net:3013/api/nagios/sets.cfg #{e}" else puts "Fetching: http://db.net:3013/api/nagios/sets.cfg" end
额外优化建议
建议扩展异常捕获的范围,覆盖其他常见的网络异常场景,避免其他网络问题导致函数执行失败:
# 同时捕获连接拒绝、连接超时、读取超时、DNS解析失败等常见网络异常 rescue Errno::ECONNREFUSED, Net::OpenTimeout, Net::ReadTimeout, SocketError => e
内容的提问来源于stack exchange,提问作者Maxim Maximov
相关产品推荐
相关产品推荐

