提交 07a4c76a 编写于 作者: A Andrew White

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
上级 e7e81b45
* 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
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册