Only raise DelegationError if it's is the source of the exception
This fixes situations where nested NoMethodError exceptions are masked by delegations. This would cause confusion especially where there was a problem in the Rails booting process because of a delegation in the routes reloading code. Fixes #10559
This commit is contained in:
parent
e7e81b4580
commit
07a4c76a07
@ -1,3 +1,9 @@
|
||||
* Only raise `Module::DelegationError` if it's the source of the exception.
|
||||
|
||||
Fixes #10559
|
||||
|
||||
*Andrew White*
|
||||
|
||||
* Make `Time.at_with_coercion` retain the second fraction and return local time.
|
||||
|
||||
Fixes #11350
|
||||
|
@ -186,8 +186,9 @@ def #{method_prefix}#{method}(#{definition}) # def customer_name(*args, &
|
||||
def #{method_prefix}#{method}(#{definition}) # def customer_name(*args, &block)
|
||||
_ = #{to} # _ = client
|
||||
_.#{method}(#{definition}) # _.name(*args, &block)
|
||||
rescue NoMethodError # rescue NoMethodError
|
||||
if _.nil? # if _.nil?
|
||||
rescue NoMethodError => e # rescue NoMethodError => e
|
||||
location = "%s:%d:in `%s'" % [__FILE__, __LINE__ - 2, '#{method_prefix}#{method}'] # location = "%s:%d:in `%s'" % [__FILE__, __LINE__ - 2, 'customer_name']
|
||||
if _.nil? && e.backtrace.first == location # if _.nil? && e.backtrace.first == location
|
||||
#{exception} # # add helpful message to the exception
|
||||
else # else
|
||||
raise # raise
|
||||
|
@ -66,6 +66,23 @@ def self.table_name
|
||||
delegate :name, :to => :client, :prefix => false
|
||||
end
|
||||
|
||||
Product = Struct.new(:name) do
|
||||
delegate :name, :to => :manufacturer, :prefix => true
|
||||
delegate :name, :to => :type, :prefix => true
|
||||
|
||||
def manufacturer
|
||||
@manufacturer ||= begin
|
||||
nil.unknown_method
|
||||
end
|
||||
end
|
||||
|
||||
def type
|
||||
@type ||= begin
|
||||
nil.type_name
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class ParameterSet
|
||||
delegate :[], :[]=, :to => :@params
|
||||
|
||||
@ -264,6 +281,16 @@ def test_delegation_invokes_the_target_exactly_once
|
||||
assert_equal [3], se.ints
|
||||
end
|
||||
|
||||
def test_delegation_doesnt_mask_nested_no_method_error_on_nil_receiver
|
||||
product = Product.new('Widget')
|
||||
|
||||
# Nested NoMethodError is a different name from the delegation
|
||||
assert_raise(NoMethodError) { product.manufacturer_name }
|
||||
|
||||
# Nested NoMethodError is the same name as the delegation
|
||||
assert_raise(NoMethodError) { product.type_name }
|
||||
end
|
||||
|
||||
def test_parent
|
||||
assert_equal Yz::Zy, Yz::Zy::Cd.parent
|
||||
assert_equal Yz, Yz::Zy.parent
|
||||
|
Loading…
Reference in New Issue
Block a user