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

Throw JavaScript exceptions from Ruby

This commit is contained in:
Charles Lowell 2015-08-12 20:18:55 +03:00
parent 2c0b979a7e
commit c9b43ff46c
6 changed files with 69 additions and 3 deletions

50
ext/v8/exception.h Normal file
View file

@ -0,0 +1,50 @@
// -*- mode: c++ -*-
#ifndef RR_EXCEPTION_H
#define RR_EXCEPTION_H
#include "rr.h"
namespace rr {
class Exception {
public:
static inline void Init() {
ClassBuilder("Exception").
defineSingletonMethod("RangeError", &RangeError).
defineSingletonMethod("ReferenceError", &ReferenceError).
defineSingletonMethod("SyntaxError", &SyntaxError).
defineSingletonMethod("TypeError", &TypeError).
defineSingletonMethod("Error", &Error);
}
static VALUE RangeError(VALUE self, VALUE rb_message) {
String message(rb_message);
Locker lock(message);
return Value(message, v8::Exception::RangeError(message));
}
static VALUE ReferenceError(VALUE self, VALUE rb_message) {
String message(rb_message);
Locker lock(message);
return Value(message, v8::Exception::ReferenceError(message));
}
static VALUE SyntaxError(VALUE self, VALUE rb_message) {
String message(rb_message);
Locker lock(message);
return Value(message, v8::Exception::SyntaxError(message));
}
static VALUE TypeError(VALUE self, VALUE rb_message) {
String message(rb_message);
Locker lock(message);
return Value(message, v8::Exception::TypeError(message));
}
static VALUE Error(VALUE self, VALUE rb_message) {
String message(rb_message);
Locker lock(message);
return Value(message, v8::Exception::Error(message));
}
};
}
#endif /* RR_EXCEPTION_H */

View file

@ -46,12 +46,12 @@ extern "C" {
StackFrame::Init();
StackTrace::Init();
Message::Init();
Exception::Init();
TryCatch::Init();
// Invocation::Init();
// Constants::Init();
// Template::Init();
// Exception::Init();
// ResourceConstraints::Init();
// HeapStatistics::Init();
}

View file

@ -9,7 +9,7 @@ namespace rr {
rb_eval_string("require 'v8/retained_objects'");
ClassBuilder("Isolate").
defineSingletonMethod("New", &New).
defineMethod("ThrowException", &ThrowException).
defineMethod("SetCaptureStackTraceForUncaughtExceptions", &SetCaptureStackTraceForUncaughtExceptions).
defineMethod("IdleNotificationDeadline", &IdleNotificationDeadline).
@ -33,6 +33,12 @@ namespace rr {
return Isolate(isolate);
}
VALUE Isolate::ThrowException(VALUE self, VALUE error) {
Isolate isolate(self);
Locker lock(isolate);
return Value(isolate, isolate->ThrowException(Value(error)));
}
VALUE Isolate::SetCaptureStackTraceForUncaughtExceptions(VALUE self, VALUE capture, VALUE stack_limit, VALUE options) {
Isolate isolate(self);
Locker lock(isolate);

View file

@ -31,6 +31,7 @@ namespace rr {
static VALUE New(VALUE self);
static VALUE SetCaptureStackTraceForUncaughtExceptions(VALUE self, VALUE capture, VALUE stack_limit, VALUE options);
static VALUE ThrowException(VALUE self, VALUE error);
inline Isolate(IsolateData* data_) : data(data_) {}
inline Isolate(v8::Isolate* isolate) :

View file

@ -72,6 +72,7 @@ inline VALUE not_implemented(const char* message) {
#include "stack-frame.h"
#include "stack-trace.h"
#include "message.h"
#include "exception.h"
#include "try-catch.h"
#endif

View file

@ -60,11 +60,19 @@ describe V8::C::TryCatch do
end
end
it "sees JavaScript exceptions thrown from Ruby" do
V8::C::TryCatch(@isolate) do |trycatch|
message = V8::C::String::NewFromUtf8(@isolate, "boom!")
@isolate.ThrowException(V8::C::Exception::Error(message))
expect(trycatch.HasCaught).to be_truthy
end
end
it "won't die on a ruby exception" do
expect {
V8::C::TryCatch(@isolate) do |trycatch|
fail "boom!"
end
}.to raise_error
}.to raise_error RuntimeError, "boom!"
end
end