我正在调用一个函数来从源类型中获取数据,因此我创建了一个名为FileReader
的超类和几个类,每个类用于FTP,SFTP,Google Drive等。每个类都将继承和实现一个get_data
函数。
我想捕获gems返回的异常,以便我们不会将外部因素报告为Rollbar的错误报告,因此我们会在找不到文件时抢救异常并向用户返回正确的消息,请求定时救援块是超类,因为SocketError,EOFError等异常在所有子类上都很常见,所以我试图让我的代码保持干燥。
class FileReader
def get_data
nil
end
def read
data = nil
begin
data = get_data
rescue EOFError => e
# return error message
rescue SocketError => e
# return error message
rescue OpenURI::HTTPError => e
# return error message
rescue Net::FTPPermError => e
# return error message
rescue Net::SFTP::StatusException => e
# return error message
rescue Errno::ETIMEDOUT => e
# return error message
rescue Exception => e
puts e.message
puts e.backtrace.join("\n")
Rollbar.error(e, :source => self)
# return error message
end
return data
end
end
FtpFileReader继承FileReader类以实现get_data
函数。
class FtpFileReader < FileReader
def get_data
# connect to ftp, get file, return data
# no begin and rescue block here
end
end
我的read
方法是从我的Rails模型中调用的。
但是抓住这些例外对我来说很棘手。
调用方法read
正在捕获此异常,如果我在其中实现了一个救援块,那么FileReader#get_data
方法也会捕获相同的异常吗?
我应该在FileReader get_data
方法而不是read
中捕获这些异常吗?或者我应该在子类本身捕获这些特定的异常并在子类中的每个get_data
方法中返回错误消息?最终捕获的类将更大但重复EOFError,SocketError不是那么干。在这种情况下处理异常的最佳方法是什么?
答案 0 :(得分:1)
首先,永远不要从Exception
救出(除非你重新加注,即便如此,也要问问自己为什么要这样做)。从StandardError
救出。阅读它here。
我只会在那些子类中为特定于子类的错误定义rescue
,以便该特定逻辑可以完全与所讨论的子类隔离。您可以按照建议执行此操作,方法是将特定错误捕获移至get_data
方法。但是您可以考虑定义一个新方法,以便可以使用非抢救方法(可能仅用于调试目的,或者从您想要以不同方式处理错误的另一个控制器)。这是我考虑这样做的一种方式:
class FtpFileReader < FileReader
def get_data
get_data!
rescue Net::FTPPermErro => e
# return error message
end
def get_data!
# do stuff
end
end