I'm working in Rails 6. I've defined an error class inside the class that raises it:
class MyClass < ApplicationRecord
...
class CustomError < StandardError
attr_reader :param
def initialize(param)
@param = param
end
end
end
I try to rescue it in client code, but this doesn't catch it:
rescue MyClass::CustomError => e
On the other hand this raises uninitialized constant on CustomError, exactly as I'd expect:
rescue CustomError => e
What about this?
rescue MyClass::CustomError => e
raise unless e.instance_of? MyClass::CustomError
# do some real error handling
...
end
instance_of? doesn't recognise the error and it re-raises.
I've even tried:
class MyClass < ApplicationRecord
...
end
class MyClass::CustomError < StandardError
attr_reader :para
def initialize(param)
@param = param
end
end
That's no better.
2 things that have worked are both code smells:
Defining the error outside the containing class, with no namespacing
Rescuing a generic error:
rescue => e
It also works fine in MiniTest:
e = assert_raises(MyClass::CustomError) do
...
end
It feels like the error class name CustomError simply isn't resolving to MyClass::CustomError in app code, but the client code needs the containing classname to resolve the class at all.
More likely though I'm just doing something a bit naive/stupid!
Additional info:
- Ruby 2.7.1
- Rails 6.0.3.3
- The class raising the error and the class handling it are both model classes (a bit unusual)
- The runtime class raising the error is a child of
MyClass:MyChild < MyClass < ActiveRecord(also unusual)