Reputation: 2349
I believe in most of the cases when exceptions occur, they do occur around an object, as a result of attempt to call a method on an object, or they occur while executing some code which is part of some method belonging to an object.
How I come to know this object from the given Exception
instance?
Example
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
In my particular case, I want to know for which AR object SerializationTypeMismatch occurred.
Am not interested in e.message or backtrace in this case, I also checked e.methods, but did not find the way out to know the associated object.
Upvotes: 1
Views: 171
Reputation: 11588
I believe in most of the cases when exceptions occur, they do occur around an object, as a result of attempt to call a method on an object, or they occur while executing some code which is part of some method belonging to an object.
But that's not true in all cases, and in general there is no relationship between an Exception that is raised and an object "around which" it occurred, since there may not always be an object.
For instance, LoadError is raised when a required file (e.g. a Ruby script) fails to load. That doesn't really relate to any particular object instance. I don't believe the initializer methods for any of the standard exception classes accept an argument for storing the object related to that exception, so there isn't a direct way to map back to the originating object.
If you're unable to map back to the ActiveRecord object where the error is occurring, perhaps your begin
/rescue
block is placed "too high" in the stack of code being called. For instance, you may have something like this each
loop in your begin
block:
begin
items.each do |item|
raise RuntimeError unless item == "foo"
end
rescue RuntimeError => e
# which item caused the error?
end
In that scenario you have no way to know which item caused the error, but you could restructure your begin
block to more directly wrap the code as follows:
items.each do |item|
begin
raise RuntimeError unless item == "foo"
rescue RuntimeError => e
# the object that raised the exception must be 'item'
end
end
This is a contrived example of course, but hopefully it illustrates the technique of wrapping your begin
/rescue
block more closely around the code that may raise exceptions, so there is no ambiguity about which object is causing the problem.
Upvotes: 2