diff --git a/ChangeLog b/ChangeLog index 307ad599ed..41d0aaa06e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +Sat Dec 11 20:12:21 2004 Masatoshi SEKI + + * lib/drb/drb.rb: add DRbRemoteError. [ruby-list:40348], + [ruby-list:40390] + + * test/drb/drbtest.rb: ditto. + + * test/drb/ut_drb.rb: ditto. + Sat Dec 11 12:41:55 2004 NAKAMURA Usaku * eval.c (run_trap_eval): prototype; avoid VC++ warnings. diff --git a/lib/drb/drb.rb b/lib/drb/drb.rb index c90259f87e..e92131f1d8 100644 --- a/lib/drb/drb.rb +++ b/lib/drb/drb.rb @@ -430,6 +430,15 @@ module DRb end end + class DRbRemoteError < DRbError + def initialize(error) + @reason = error.class.to_s + super("#{error.message} (#{error.class})") + set_backtrace(error.backtrace) + end + attr_reader :reason + end + # Class wrapping a marshalled object whose type is unknown locally. # # If an object is returned by a method invoked over drb, but the @@ -539,12 +548,12 @@ module DRb @argc_limit = config[:argc_limit] end - def dump(obj) # :nodoc: - obj = DRbObject.new(obj) if obj.kind_of? DRbUndumped + def dump(obj, error=false) # :nodoc: + obj = make_proxy(obj, error) if obj.kind_of? DRbUndumped begin str = Marshal::dump(obj) rescue - str = Marshal::dump(DRbObject.new(obj)) + str = Marshal::dump(make_proxy(obj, error)) end [str.size].pack('N') + str end @@ -602,7 +611,7 @@ module DRb end def send_reply(stream, succ, result) # :nodoc: - stream.write(dump(succ) + dump(result)) + stream.write(dump(succ) + dump(result, !succ)) rescue raise(DRbConnError, $!.message, $!.backtrace) end @@ -612,6 +621,15 @@ module DRb result = load(stream) [succ, result] end + + private + def make_proxy(obj, error=false) + if error + DRbRemoteError.new(obj) + else + DRbObject.new(obj) + end + end end # Module managing the underlying network protocol(s) used by drb. diff --git a/test/drb/drbtest.rb b/test/drb/drbtest.rb index 777f88fbee..7f2c46d273 100644 --- a/test/drb/drbtest.rb +++ b/test/drb/drbtest.rb @@ -227,6 +227,19 @@ module DRbCore assert_kind_of(DRbObject, v) end end + + def test_11_remote_no_method_error + assert_raises(DRb::DRbRemoteError) do + @there.remote_no_method_error + end + begin + @there.remote_no_method_error + rescue + error = $! + assert_match(/^undefined method .*\(NoMethodError\)/, error.message) + assert_equal('NoMethodError', error.reason) + end + end end module DRbAry diff --git a/test/drb/ut_drb.rb b/test/drb/ut_drb.rb index e7eedf8864..b0d3a5be9a 100644 --- a/test/drb/ut_drb.rb +++ b/test/drb/ut_drb.rb @@ -66,6 +66,10 @@ class DRbEx raise UError end + def remote_no_method_error + invoke_no_method(self) + end + def test_yield yield yield([])