mirror of
https://github.com/rubyjs/mini_racer
synced 2023-03-27 23:21:28 -04:00
Add location for ParseErrors, clean up message and backtrace for Runtime errors
fixes #10
This commit is contained in:
parent
7cc8ed86d5
commit
f01067f4ff
3 changed files with 47 additions and 27 deletions
|
@ -106,30 +106,40 @@ nogvl_context_eval(void* arg) {
|
|||
|
||||
result->executed = !maybe_value.IsEmpty();
|
||||
|
||||
if (!result->executed) {
|
||||
if (trycatch.HasCaught()) {
|
||||
if (!trycatch.Exception()->IsNull()) {
|
||||
result->message = new Persistent<Value>();
|
||||
result->message->Reset(isolate, trycatch.Exception()->ToString());
|
||||
} else if(trycatch.HasTerminated()) {
|
||||
result->terminated = true;
|
||||
result->message = new Persistent<Value>();
|
||||
Local<String> tmp = String::NewFromUtf8(isolate, "JavaScript was terminated (either by timeout or explicitly)");
|
||||
result->message->Reset(isolate, tmp);
|
||||
}
|
||||
|
||||
if (!trycatch.StackTrace().IsEmpty()) {
|
||||
result->backtrace = new Persistent<Value>();
|
||||
result->backtrace->Reset(isolate, trycatch.StackTrace()->ToString());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (result->executed) {
|
||||
Persistent<Value>* persistent = new Persistent<Value>();
|
||||
persistent->Reset(isolate, maybe_value.ToLocalChecked());
|
||||
result->value = persistent;
|
||||
}
|
||||
}
|
||||
|
||||
if (!result->executed || !result->parsed) {
|
||||
if (trycatch.HasCaught()) {
|
||||
if (!trycatch.Exception()->IsNull()) {
|
||||
result->message = new Persistent<Value>();
|
||||
Local<Message> message = trycatch.Message();
|
||||
char buf[1000];
|
||||
int len;
|
||||
len = snprintf(buf, sizeof(buf), "%s at %s:%i:%i", *String::Utf8Value(message->Get()),
|
||||
*String::Utf8Value(message->GetScriptResourceName()->ToString()),
|
||||
message->GetLineNumber(),
|
||||
message->GetStartColumn());
|
||||
|
||||
Local<String> v8_message = String::NewFromUtf8(isolate, buf, NewStringType::kNormal, (int)len).ToLocalChecked();
|
||||
result->message->Reset(isolate, v8_message);
|
||||
} else if(trycatch.HasTerminated()) {
|
||||
result->terminated = true;
|
||||
result->message = new Persistent<Value>();
|
||||
Local<String> tmp = String::NewFromUtf8(isolate, "JavaScript was terminated (either by timeout or explicitly)");
|
||||
result->message->Reset(isolate, tmp);
|
||||
}
|
||||
if (!trycatch.StackTrace().IsEmpty()) {
|
||||
result->backtrace = new Persistent<Value>();
|
||||
result->backtrace->Reset(isolate, trycatch.StackTrace()->ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -191,7 +201,7 @@ static VALUE convert_v8_to_ruby(Isolate* isolate, Handle<Value> &value) {
|
|||
}
|
||||
|
||||
Local<String> rstr = value->ToString();
|
||||
return rb_enc_str_new(*v8::String::Utf8Value(rstr), rstr->Utf8Length(), rb_enc_find("utf-8"));
|
||||
return rb_enc_str_new(*String::Utf8Value(rstr), rstr->Utf8Length(), rb_enc_find("utf-8"));
|
||||
}
|
||||
|
||||
static Handle<Value> convert_ruby_to_v8(Isolate* isolate, VALUE value) {
|
||||
|
@ -201,7 +211,8 @@ static Handle<Value> convert_ruby_to_v8(Isolate* isolate, VALUE value) {
|
|||
Local<Object> object;
|
||||
VALUE hash_as_array;
|
||||
VALUE pair;
|
||||
int length,i;
|
||||
int i;
|
||||
long length;
|
||||
|
||||
switch (TYPE(value)) {
|
||||
case T_FIXNUM:
|
||||
|
@ -218,7 +229,7 @@ static Handle<Value> convert_ruby_to_v8(Isolate* isolate, VALUE value) {
|
|||
return scope.Escape(False(isolate));
|
||||
case T_ARRAY:
|
||||
length = RARRAY_LEN(value);
|
||||
array = Array::New(isolate, length);
|
||||
array = Array::New(isolate, (int)length);
|
||||
for(i=0; i<length; i++) {
|
||||
array->Set(i, convert_ruby_to_v8(isolate, rb_ary_entry(value, i)));
|
||||
}
|
||||
|
@ -320,13 +331,12 @@ static VALUE rb_context_eval_unsafe(VALUE self, VALUE str) {
|
|||
}
|
||||
|
||||
if (!eval_result.executed) {
|
||||
|
||||
VALUE ruby_exception = rb_iv_get(self, "@current_exception");
|
||||
if (ruby_exception == Qnil) {
|
||||
ruby_exception = eval_result.terminated ? rb_eScriptTerminatedError : rb_eScriptRuntimeError;
|
||||
// exception report about what happened
|
||||
if(TYPE(message) == T_STRING && TYPE(backtrace) == T_STRING) {
|
||||
rb_raise(ruby_exception, "%s/n%s", RSTRING_PTR(message), RSTRING_PTR(backtrace));
|
||||
if(TYPE(backtrace) == T_STRING) {
|
||||
rb_raise(ruby_exception, "%s", RSTRING_PTR(backtrace));
|
||||
} else if(TYPE(message) == T_STRING) {
|
||||
rb_raise(ruby_exception, "%s", RSTRING_PTR(message));
|
||||
} else {
|
||||
|
|
|
@ -5,7 +5,6 @@ require "thread"
|
|||
module MiniRacer
|
||||
|
||||
class EvalError < StandardError; end
|
||||
|
||||
class ScriptTerminatedError < EvalError; end
|
||||
class ParseError < EvalError; end
|
||||
|
||||
|
@ -18,7 +17,6 @@ module MiniRacer
|
|||
else
|
||||
@js_backtrace = nil
|
||||
end
|
||||
|
||||
super(message)
|
||||
end
|
||||
|
||||
|
@ -31,7 +29,6 @@ module MiniRacer
|
|||
val
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
# helper class returned when we have a JavaScript function
|
||||
|
|
|
@ -87,6 +87,19 @@ class MiniRacerTest < Minitest::Test
|
|||
end
|
||||
end
|
||||
|
||||
def test_it_handles_malformed_js_with_backtrace
|
||||
context = MiniRacer::Context.new
|
||||
assert_raises MiniRacer::ParseError do
|
||||
begin
|
||||
context.eval("var i;\ni=2;\nI am not JavaScript {")
|
||||
rescue => e
|
||||
# I <parse error> am not
|
||||
assert_match(/3:2/, e.message)
|
||||
raise
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def test_it_remembers_stuff_in_context
|
||||
context = MiniRacer::Context.new
|
||||
context.eval('var x = function(){return 22;}')
|
||||
|
|
Loading…
Reference in a new issue