我相信在发生异常的大多数情况下,它们确实发生在对象周围,因为尝试在对象上调用方法,或者在执行某些代码时发生,这些代码属于属于某个方法的某个方法的一部分。对象
我是如何从给定的Exception
实例中了解此对象的?
实施例
begin
....
rescue ActiveRecord::SerializationTypeMismatch => e
object = e.some_method_which_will_return_active_record_object
rescue => e
object = e.get_me_object_around_which_this_happened
end
在我的特定情况下,我想知道发生了哪个AR对象SerializationTypeMismatch。
在这种情况下我对e.message或backtrace不感兴趣,我也检查了e.methods,但没有找到解决相关对象的方法。
答案 0 :(得分:2)
我相信在发生异常的大多数情况下,它们确实发生在对象周围,因为尝试在对象上调用方法,或者在执行某些代码时发生,这些代码属于属于某个方法的某个方法的一部分。对象
但是在所有情况下都不是这样,并且通常在引发的Exception和它周围发生的对象之间没有任何关系,因为可能并不总是存在对象。
例如,当无法加载所需文件(例如Ruby脚本)时,会引发LoadError。这与任何特定的对象实例都没有关系。我不相信任何standard exception classes的初始化方法接受存储与该异常相关的对象的参数,因此没有直接的方法来映射回原始对象。
如果您无法映射回发生错误的ActiveRecord对象,则可能是您的begin
/ rescue
块在被调用的代码堆栈中“过高”。例如,您的each
块中可能包含此begin
循环:
begin
items.each do |item|
raise RuntimeError unless item == "foo"
end
rescue RuntimeError => e
# which item caused the error?
end
在这种情况下,您无法知道哪个项导致了错误,但您可以重构begin
块以更直接地包装代码,如下所示:
items.each do |item|
begin
raise RuntimeError unless item == "foo"
rescue RuntimeError => e
# the object that raised the exception must be 'item'
end
end
这当然是一个人为的例子,但希望它说明了将begin
/ rescue
块更紧密地包裹在可能引发异常的代码周围的技术,因此对于哪个对象没有歧义引起了这个问题。