mirror of
https://github.com/rubyjs/mini_racer
synced 2023-03-27 23:21:28 -04:00
correct the exception structure
This commit is contained in:
parent
1218198afa
commit
eb826ae48a
3 changed files with 30 additions and 12 deletions
|
@ -27,6 +27,7 @@ typedef struct {
|
|||
typedef struct {
|
||||
bool parsed;
|
||||
bool executed;
|
||||
bool terminated;
|
||||
Persistent<Value>* value;
|
||||
Persistent<Value>* message;
|
||||
Persistent<Value>* backtrace;
|
||||
|
@ -39,8 +40,11 @@ typedef struct {
|
|||
EvalResult* result;
|
||||
} EvalParams;
|
||||
|
||||
Platform* current_platform = NULL;
|
||||
static VALUE rb_eJavaScriptError;
|
||||
static VALUE rb_eScriptTerminatedError;
|
||||
static VALUE rb_eParseError;
|
||||
static VALUE rb_eScriptRuntimeError;
|
||||
|
||||
static Platform* current_platform = NULL;
|
||||
|
||||
static void init_v8() {
|
||||
if (current_platform == NULL) {
|
||||
|
@ -76,6 +80,7 @@ nogvl_context_eval(void* arg) {
|
|||
MaybeLocal<Script> parsed_script = Script::Compile(context, *eval_params->eval);
|
||||
result->parsed = !parsed_script.IsEmpty();
|
||||
result->executed = false;
|
||||
result->terminated = false;
|
||||
result->value = NULL;
|
||||
|
||||
if (!result->parsed) {
|
||||
|
@ -104,6 +109,7 @@ nogvl_context_eval(void* arg) {
|
|||
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);
|
||||
|
@ -272,9 +278,9 @@ static VALUE rb_context_eval_unsafe(VALUE self, VALUE str) {
|
|||
// a v8 scope, if we do the scope is never cleaned up properly and we leak
|
||||
if (!eval_result.parsed) {
|
||||
if(TYPE(message) == T_STRING) {
|
||||
rb_raise(rb_eJavaScriptError, "%s", RSTRING_PTR(message));
|
||||
rb_raise(rb_eParseError, "%s", RSTRING_PTR(message));
|
||||
} else {
|
||||
rb_raise(rb_eJavaScriptError, "Unknown JavaScript Error during parse");
|
||||
rb_raise(rb_eParseError, "Unknown JavaScript Error during parse");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -282,13 +288,14 @@ static VALUE rb_context_eval_unsafe(VALUE self, VALUE str) {
|
|||
|
||||
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(rb_eJavaScriptError, "%s/n%s", RSTRING_PTR(message), RSTRING_PTR(backtrace));
|
||||
rb_raise(ruby_exception, "%s/n%s", RSTRING_PTR(message), RSTRING_PTR(backtrace));
|
||||
} else if(TYPE(message) == T_STRING) {
|
||||
rb_raise(rb_eJavaScriptError, "%s", RSTRING_PTR(message));
|
||||
rb_raise(ruby_exception, "%s", RSTRING_PTR(message));
|
||||
} else {
|
||||
rb_raise(rb_eJavaScriptError, "Unknown JavaScript Error during execution");
|
||||
rb_raise(ruby_exception, "Unknown JavaScript Error during execution");
|
||||
}
|
||||
} else {
|
||||
VALUE rb_str = rb_funcall(ruby_exception, rb_intern("to_s"), 0);
|
||||
|
@ -498,7 +505,12 @@ extern "C" {
|
|||
{
|
||||
VALUE rb_mMiniRacer = rb_define_module("MiniRacer");
|
||||
VALUE rb_cContext = rb_define_class_under(rb_mMiniRacer, "Context", rb_cObject);
|
||||
rb_eJavaScriptError = rb_define_class_under(rb_mMiniRacer, "JavaScriptError", rb_eStandardError);
|
||||
|
||||
VALUE rb_eEvalError = rb_define_class_under(rb_mMiniRacer, "EvalError", rb_eStandardError);
|
||||
rb_eScriptTerminatedError = rb_define_class_under(rb_mMiniRacer, "ScriptTerminatedError", rb_eEvalError);
|
||||
rb_eParseError = rb_define_class_under(rb_mMiniRacer, "ParseError", rb_eEvalError);
|
||||
rb_eScriptRuntimeError = rb_define_class_under(rb_mMiniRacer, "RuntimeError", rb_eEvalError);
|
||||
|
||||
VALUE rb_cExternalFunction = rb_define_class_under(rb_cContext, "ExternalFunction", rb_cObject);
|
||||
rb_define_method(rb_cContext, "stop", (VALUE(*)(...))&rb_context_stop, 0);
|
||||
rb_define_alloc_func(rb_cContext, allocate);
|
||||
|
|
|
@ -3,7 +3,13 @@ require "mini_racer_extension"
|
|||
require "thread"
|
||||
|
||||
module MiniRacer
|
||||
class JavaScriptError < StandardError
|
||||
|
||||
class EvalError < StandardError; end
|
||||
|
||||
class ScriptTerminatedError < EvalError; end
|
||||
class ParseError < EvalError; end
|
||||
|
||||
class RuntimeError < EvalError
|
||||
def initialize(message)
|
||||
message, js_backtrace = message.split("\n", 2)
|
||||
if js_backtrace && !js_backtrace.empty?
|
||||
|
|
|
@ -38,7 +38,7 @@ class MiniRacerTest < Minitest::Test
|
|||
exp = e
|
||||
end
|
||||
|
||||
assert_equal MiniRacer::JavaScriptError, exp.class
|
||||
assert_equal MiniRacer::RuntimeError, exp.class
|
||||
|
||||
assert_match(/boom/, exp.message)
|
||||
assert_match(/foo/, exp.backtrace[0])
|
||||
|
@ -62,7 +62,7 @@ class MiniRacerTest < Minitest::Test
|
|||
exp = e
|
||||
end
|
||||
|
||||
assert_equal MiniRacer::JavaScriptError, exp.class
|
||||
assert_equal MiniRacer::ScriptTerminatedError, exp.class
|
||||
assert_match(/terminated/, exp.message)
|
||||
|
||||
end
|
||||
|
@ -77,7 +77,7 @@ class MiniRacerTest < Minitest::Test
|
|||
|
||||
def test_it_handles_malformed_js
|
||||
context = MiniRacer::Context.new
|
||||
assert_raises do
|
||||
assert_raises MiniRacer::ParseError do
|
||||
context.eval('I am not JavaScript {')
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Add table
Reference in a new issue