Skip to content

Commit

Permalink
Fixed handling of an exception within a class constructor
Browse files Browse the repository at this point in the history
  • Loading branch information
Roland Eischer committed Oct 16, 2018
1 parent 930e498 commit fcf0a29
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 2 deletions.
18 changes: 17 additions & 1 deletion test/test_class.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,14 @@ int Y::instance_count = 0;

struct Z {};

class E
{
public:
E(v8::FunctionCallbackInfo<v8::Value> const& args) {
v8pp::throw_ex(args.GetIsolate(), "MyException");
}
};

namespace v8pp {
template<>
struct factory<Y, v8pp::raw_ptr_traits>
Expand Down Expand Up @@ -150,6 +158,11 @@ void test_class_()
.set("useX_ptr", &Y::useX_ptr<Traits>)
;

v8pp::class_<E, Traits> E_class(isolate);
E_class
.template ctor<v8::FunctionCallbackInfo<v8::Value> const&>()
;

check_ex<std::runtime_error>("already wrapped class X", [isolate]()
{
v8pp::class_<X, Traits> X_class(isolate);
Expand All @@ -166,6 +179,7 @@ void test_class_()
context
.set("X", X_class)
.set("Y", Y_class)
.set("E", E_class)
;

check_eq("X object", run_script<int>(context, "x = new X(); x.var += x.konst"), 100);
Expand Down Expand Up @@ -248,6 +262,8 @@ void test_class_()
v8pp::class_<Y, Traits>::destroy(isolate);
check_eq("Y count after class_<Y>::destroy", Y::instance_count,
1 + 2 * use_shared_ptr); // y1 + (y2 + y3 when use_shared_ptr)

check_eq("E exception ctor class", run_script<std::string>(context, "retError = ""; try { var e = new E(); } catch(err) { retError = err; } retError"), "MyException");
}

template<typename Traits>
Expand Down Expand Up @@ -370,4 +386,4 @@ void test_class()

test_const_instance_in_module<v8pp::raw_ptr_traits>();
test_const_instance_in_module<v8pp::shared_ptr_traits>();
}
}
13 changes: 12 additions & 1 deletion v8pp/class.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,18 @@ class object_registry final : public class_info
//assert(false && "create not allowed");
throw std::runtime_error(class_name() + " has no constructor");
}
return wrap_object(ctor_(args), true);

v8::EscapableHandleScope scope(args.GetIsolate());
v8::TryCatch try_catch(args.GetIsolate());
v8::Local<v8::Object> result;

auto ctorRes = ctor_(args);
if (try_catch.HasCaught())
try_catch.ReThrow();
else
result = wrap_object(ctorRes, true);

return scope.Escape(result);
}

pointer_type unwrap_object(v8::Local<v8::Value> value)
Expand Down

0 comments on commit fcf0a29

Please sign in to comment.