Skip to content
Browse files

JSError improvement - make sure ruby error message is kept

  • Loading branch information...
1 parent 6c84e6b commit db54adc223d8f5881fee81e533ae6ea419f27228 @kares kares committed Aug 24, 2012
Showing with 77 additions and 19 deletions.
  1. +28 −19 lib/rhino/error.rb
  2. +49 −0 spec/rhino/error_spec.rb
View
47 lib/rhino/error.rb
@@ -4,8 +4,11 @@ class JSError < StandardError
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,24 +25,10 @@ def message
# #Rhino::JS::JavaScriptException instance.
def cause
return @cause if defined?(@cause)
- @cause = begin
- if @native.respond_to?(:cause) && @native.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
+ if @native.respond_to?(:cause)
+ @native.cause
else
- @value = nil
+ @native.is_a?(JS::RhinoException) ? @native : nil
end
end
@@ -59,6 +48,14 @@ def unwrap
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 @@ def javascript_backtrace(keep_elements = false)
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
49 spec/rhino/error_spec.rb
@@ -128,6 +128,28 @@ def cause
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
@@ -140,5 +162,32 @@ def cause
fail "expected to rescue"
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

0 comments on commit db54adc

Please sign in to comment.
Something went wrong with that request. Please try again.