1
0
Fork 0
mirror of https://github.com/rubyjs/therubyrhino synced 2023-03-27 23:21:34 -04:00

JSError improvement - make sure ruby error message is kept

This commit is contained in:
kares 2012-08-24 13:02:13 +02:00
parent 6c84e6bf87
commit db54adc223
2 changed files with 77 additions and 19 deletions

View file

@ -4,8 +4,11 @@ module Rhino
def initialize(native)
@native = native # NativeException wrapping a Java Throwable
message = value ? value : ( cause ? cause.details : @native )
super(message)
if ( value = self.value(true) ) != nil
super value.is_a?(Exception) ? "#{value.class.name}: #{value.message}" : value
else
super cause ? cause.details : @native
end
end
def inspect
@ -22,26 +25,12 @@ module Rhino
# #Rhino::JS::JavaScriptException instance.
def cause
return @cause if defined?(@cause)
@cause = begin
if @native.respond_to?(:cause) && @native.cause
if @native.respond_to?(:cause)
@native.cause
else
@native.is_a?(JS::RhinoException) ? @native : nil
end
end
end
# Return the thown (native) JavaScript value.
def value
return @value if defined?(@value)
if cause.respond_to?(:value) # e.g. JavaScriptException.getValue
@value = cause.value
elsif ( unwrap = self.unwrap ) && unwrap.respond_to?(:value)
@value = unwrap.value
else
@value = nil
end
end
# Attempts to unwrap the (native) JavaScript/Java exception.
def unwrap
@ -59,6 +48,14 @@ module Rhino
end
end
# Return the thown (native) JavaScript value.
def value(unwrap = false)
return @value if defined?(@value) && ! unwrap
@value = get_value unless defined?(@value)
return @value.unwrap if unwrap && @value.respond_to?(:unwrap)
@value
end
# The backtrace is constructed using #javascript_backtrace + the Ruby part.
def backtrace
if js_backtrace = javascript_backtrace
@ -81,6 +78,18 @@ module Rhino
Rhino::JS::RhinoException.useMozillaStackStyle(false)
private
def get_value
if ( cause = self.cause ) && cause.respond_to?(:value)
cause.value # e.g. JavaScriptException.getValue
elsif ( unwrap = self.unwrap ) && unwrap.respond_to?(:value)
unwrap.value
else
nil
end
end
end
end

View file

@ -128,6 +128,28 @@ describe Rhino::JSError do
end
end
it "wrapps false value correctly" do
begin
Rhino::Context.eval "throw false"
rescue => e
e.inspect.should == '#<Rhino::JSError: false>'
e.value.should be false
else
fail "expected to rescue"
end
end
it "wrapps null value correctly" do
begin
Rhino::Context.eval "throw null"
rescue => e
e.inspect.should == '#<Rhino::JSError: null>'
e.value.should be nil
else
fail "expected to rescue"
end
end
it "raises correct error from function#apply" do
begin
context = Rhino::Context.new
@ -141,4 +163,31 @@ describe Rhino::JSError do
end
end
it "prints info about nested (ruby) error" do
context = Rhino::Context.new
klass = Class.new do
def hello(arg = 42)
raise RuntimeError, 'hello' if arg != 42
end
end
context[:Hello] = klass.new
hi = context.eval "( function hi(arg) { Hello.hello(arg); } )"
begin
hi.call(24)
rescue => e
e.should be_a Rhino::JSError
e.value.should_not be nil
e.value.should be_a Rhino::Ruby::Object
e.value(true).should be_a RuntimeError # unwraps ruby object
# prints the original message (beyond [ruby RuntimeError]) :
e.message.should == "RuntimeError: hello"
else
fail "expected to rescue"
end
# V8::JSError: hello
# from (irb):4:in `hello'
# from at hi (<eval>:1:28)
# from (irb):9
end
end