Skip to content
This repository was archived by the owner on Dec 4, 2023. It is now read-only.

Commit c9b43ff

Browse files
committed
Throw JavaScript exceptions from Ruby
1 parent 2c0b979 commit c9b43ff

6 files changed

Lines changed: 69 additions & 3 deletions

File tree

ext/v8/exception.h

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
// -*- mode: c++ -*-
2+
#ifndef RR_EXCEPTION_H
3+
#define RR_EXCEPTION_H
4+
#include "rr.h"
5+
6+
namespace rr {
7+
class Exception {
8+
public:
9+
static inline void Init() {
10+
ClassBuilder("Exception").
11+
defineSingletonMethod("RangeError", &RangeError).
12+
defineSingletonMethod("ReferenceError", &ReferenceError).
13+
defineSingletonMethod("SyntaxError", &SyntaxError).
14+
defineSingletonMethod("TypeError", &TypeError).
15+
defineSingletonMethod("Error", &Error);
16+
}
17+
18+
static VALUE RangeError(VALUE self, VALUE rb_message) {
19+
String message(rb_message);
20+
Locker lock(message);
21+
return Value(message, v8::Exception::RangeError(message));
22+
}
23+
24+
static VALUE ReferenceError(VALUE self, VALUE rb_message) {
25+
String message(rb_message);
26+
Locker lock(message);
27+
return Value(message, v8::Exception::ReferenceError(message));
28+
}
29+
30+
static VALUE SyntaxError(VALUE self, VALUE rb_message) {
31+
String message(rb_message);
32+
Locker lock(message);
33+
return Value(message, v8::Exception::SyntaxError(message));
34+
}
35+
36+
static VALUE TypeError(VALUE self, VALUE rb_message) {
37+
String message(rb_message);
38+
Locker lock(message);
39+
return Value(message, v8::Exception::TypeError(message));
40+
}
41+
42+
static VALUE Error(VALUE self, VALUE rb_message) {
43+
String message(rb_message);
44+
Locker lock(message);
45+
return Value(message, v8::Exception::Error(message));
46+
}
47+
};
48+
}
49+
50+
#endif /* RR_EXCEPTION_H */

ext/v8/init.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,12 +46,12 @@ extern "C" {
4646
StackFrame::Init();
4747
StackTrace::Init();
4848
Message::Init();
49+
Exception::Init();
4950
TryCatch::Init();
5051

5152
// Invocation::Init();
5253
// Constants::Init();
5354
// Template::Init();
54-
// Exception::Init();
5555
// ResourceConstraints::Init();
5656
// HeapStatistics::Init();
5757
}

ext/v8/isolate.cc

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ namespace rr {
99
rb_eval_string("require 'v8/retained_objects'");
1010
ClassBuilder("Isolate").
1111
defineSingletonMethod("New", &New).
12-
12+
defineMethod("ThrowException", &ThrowException).
1313
defineMethod("SetCaptureStackTraceForUncaughtExceptions", &SetCaptureStackTraceForUncaughtExceptions).
1414
defineMethod("IdleNotificationDeadline", &IdleNotificationDeadline).
1515

@@ -33,6 +33,12 @@ namespace rr {
3333
return Isolate(isolate);
3434
}
3535

36+
VALUE Isolate::ThrowException(VALUE self, VALUE error) {
37+
Isolate isolate(self);
38+
Locker lock(isolate);
39+
return Value(isolate, isolate->ThrowException(Value(error)));
40+
}
41+
3642
VALUE Isolate::SetCaptureStackTraceForUncaughtExceptions(VALUE self, VALUE capture, VALUE stack_limit, VALUE options) {
3743
Isolate isolate(self);
3844
Locker lock(isolate);

ext/v8/isolate.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ namespace rr {
3131

3232
static VALUE New(VALUE self);
3333
static VALUE SetCaptureStackTraceForUncaughtExceptions(VALUE self, VALUE capture, VALUE stack_limit, VALUE options);
34+
static VALUE ThrowException(VALUE self, VALUE error);
3435

3536
inline Isolate(IsolateData* data_) : data(data_) {}
3637
inline Isolate(v8::Isolate* isolate) :

ext/v8/rr.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ inline VALUE not_implemented(const char* message) {
7272
#include "stack-frame.h"
7373
#include "stack-trace.h"
7474
#include "message.h"
75+
#include "exception.h"
7576
#include "try-catch.h"
7677

7778
#endif

spec/c/try_catch_spec.rb

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,11 +60,19 @@
6060
end
6161
end
6262

63+
it "sees JavaScript exceptions thrown from Ruby" do
64+
V8::C::TryCatch(@isolate) do |trycatch|
65+
message = V8::C::String::NewFromUtf8(@isolate, "boom!")
66+
@isolate.ThrowException(V8::C::Exception::Error(message))
67+
expect(trycatch.HasCaught).to be_truthy
68+
end
69+
end
70+
6371
it "won't die on a ruby exception" do
6472
expect {
6573
V8::C::TryCatch(@isolate) do |trycatch|
6674
fail "boom!"
6775
end
68-
}.to raise_error
76+
}.to raise_error RuntimeError, "boom!"
6977
end
7078
end

0 commit comments

Comments
 (0)