mirror of
https://github.com/rubyjs/therubyracer
synced 2023-03-27 23:21:42 -04:00
properly report source:line:column on SyntaxErrors.
This commit is contained in:
parent
22727d1e4a
commit
59ac87f37d
3 changed files with 44 additions and 13 deletions
|
|
@ -24,7 +24,8 @@ namespace {
|
||||||
}
|
}
|
||||||
|
|
||||||
VALUE GetStackTrace(VALUE self) {
|
VALUE GetStackTrace(VALUE self) {
|
||||||
return rr_v82rb(unwrap(self)->GetStackTrace());
|
Handle<StackTrace> trace = unwrap(self)->GetStackTrace();
|
||||||
|
return trace.IsEmpty() ? Qnil : rr_v82rb(trace);
|
||||||
}
|
}
|
||||||
|
|
||||||
VALUE GetLineNumber(VALUE self) {
|
VALUE GetLineNumber(VALUE self) {
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,6 @@ module V8
|
||||||
else
|
else
|
||||||
@value = ex
|
@value = ex
|
||||||
message = ex.to_s
|
message = ex.to_s
|
||||||
@boundaries.first.jsframes << 'at [???].js'
|
|
||||||
end
|
end
|
||||||
return message
|
return message
|
||||||
end
|
end
|
||||||
|
|
@ -88,13 +87,31 @@ module V8
|
||||||
end
|
end
|
||||||
|
|
||||||
def parse_js_frames(try)
|
def parse_js_frames(try)
|
||||||
|
#I can't figure out why V8 is not capturing the stacktrace here
|
||||||
|
#in terms of StackTrace and StackFrame objects, so we have to
|
||||||
|
#parse the string.
|
||||||
raw = @to.rb(try.StackTrace())
|
raw = @to.rb(try.StackTrace())
|
||||||
if raw && !raw.empty?
|
if raw && !raw.empty? && !syntax_error?(try)
|
||||||
raw.split("\n")[1..-1].tap do |frames|
|
raw.split("\n")[1..-1].tap do |frames|
|
||||||
frames.each {|frame| frame.strip!.chomp!(",")}
|
frames.each {|frame| frame.strip!.chomp!(",")}
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
[]
|
msg = try.Message()
|
||||||
|
["at #{@to.rb(msg.GetScriptResourceName())}:#{msg.GetLineNumber()}:#{msg.GetStartColumn() + 1}"]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
#Syntax errors are weird in that they have a non-empty stack trace
|
||||||
|
#but it does not contain any source location information, so
|
||||||
|
#in these instances, we have to pull it out of the Message object
|
||||||
|
#in the TryCatch. Is there a better way to detect a syntax error
|
||||||
|
def syntax_error?(try)
|
||||||
|
ex = try.Exception()
|
||||||
|
if ex && ex.kind_of?(V8::C::Object)
|
||||||
|
type = ex.Get("constructor")
|
||||||
|
type && type.kind_of?(V8::C::Function) && type.GetName().AsciiValue == "SyntaxError"
|
||||||
|
else
|
||||||
|
false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
||||||
|
|
||||||
describe V8::JSError do
|
describe V8::JSError do
|
||||||
|
|
||||||
before(:each) do
|
before(:each) do
|
||||||
@cxt = V8::Context.new
|
@cxt = V8::Context.new
|
||||||
@cxt['one'] = lambda do
|
@cxt['one'] = lambda do
|
||||||
|
|
@ -11,13 +11,13 @@ describe V8::JSError do
|
||||||
@cxt.eval('three()', 'two.js')
|
@cxt.eval('three()', 'two.js')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
it "captures a message without over nesting when the error is an error" do
|
it "captures a message without over nesting when the error is an error" do
|
||||||
throw! do |e|
|
throw! do |e|
|
||||||
e.message.should == "BOOM!"
|
e.message.should == "BOOM!"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
it "captures the js message without over nesting when the error is a normal object" do
|
it "captures the js message without over nesting when the error is a normal object" do
|
||||||
throw!('{foo: "bar"}') do |e|
|
throw!('{foo: "bar"}') do |e|
|
||||||
e.message.should == "[object Object]"
|
e.message.should == "[object Object]"
|
||||||
|
|
@ -26,7 +26,7 @@ describe V8::JSError do
|
||||||
e.message.should == "bar"
|
e.message.should == "bar"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
it "captures a thrown value as the message" do
|
it "captures a thrown value as the message" do
|
||||||
throw!('"BOOM!"') do |e|
|
throw!('"BOOM!"') do |e|
|
||||||
e.message.should == "BOOM!"
|
e.message.should == "BOOM!"
|
||||||
|
|
@ -35,7 +35,7 @@ describe V8::JSError do
|
||||||
e.message.should == '6'
|
e.message.should == '6'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
it "has a reference to the root javascript cause" do
|
it "has a reference to the root javascript cause" do
|
||||||
throw!('"I am a String"') do |e|
|
throw!('"I am a String"') do |e|
|
||||||
e.should_not be_in_ruby
|
e.should_not be_in_ruby
|
||||||
|
|
@ -43,7 +43,7 @@ describe V8::JSError do
|
||||||
e.value.should == "I am a String"
|
e.value.should == "I am a String"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
it "has a reference to the root ruby cause if one exists" do
|
it "has a reference to the root ruby cause if one exists" do
|
||||||
StandardError.new("BOOM!").tap do |bomb|
|
StandardError.new("BOOM!").tap do |bomb|
|
||||||
@cxt['boom'] = lambda do
|
@cxt['boom'] = lambda do
|
||||||
|
|
@ -58,9 +58,9 @@ describe V8::JSError do
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "backtrace" do
|
describe "backtrace" do
|
||||||
|
|
||||||
it "is mixed with ruby and javascript" do
|
it "is mixed with ruby and javascript" do
|
||||||
throw! do |e|
|
throw! do |e|
|
||||||
e.backtrace.first.should == "at three.js:1:7"
|
e.backtrace.first.should == "at three.js:1:7"
|
||||||
|
|
@ -89,10 +89,23 @@ describe V8::JSError do
|
||||||
|
|
||||||
it "includes a mystery marker when the original frame is unavailable because what got thrown wasn't an error" do
|
it "includes a mystery marker when the original frame is unavailable because what got thrown wasn't an error" do
|
||||||
throw!("6") do |e|
|
throw!("6") do |e|
|
||||||
e.backtrace.first.should == 'at [???].js'
|
e.backtrace.first.should == 'at three.js:1:1'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "has a source name and line number when there is a javascript SyntaxError" do
|
||||||
|
lambda do
|
||||||
|
@cxt.eval(<<-INVALID, 'source.js')
|
||||||
|
"this line is okay";
|
||||||
|
"this line has a syntax error because it ends with a colon":
|
||||||
|
"this line is also okay";
|
||||||
|
"how do I find out that line 2 has the syntax error?";
|
||||||
|
INVALID
|
||||||
|
end.should raise_error(V8::JSError) {|error|
|
||||||
|
error.backtrace.first.should == 'at source.js:2:60'
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
it "can start with ruby at the bottom" do
|
it "can start with ruby at the bottom" do
|
||||||
@cxt['boom'] = lambda do
|
@cxt['boom'] = lambda do
|
||||||
raise StandardError, "Bif!"
|
raise StandardError, "Bif!"
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue