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 e68d34f
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 2 deletions.
33 changes: 32 additions & 1 deletion test/test_class.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,15 @@ static X_ptr create_X(v8::FunctionCallbackInfo<v8::Value> const& args)
return x;
}

template<typename Traits, typename E_ptr = typename v8pp::class_<E, Traits>::object_pointer_type>
static E_ptr create_E(v8::FunctionCallbackInfo<v8::Value> const& args)
{
E_ptr e(new E);
if (args.Length() == 0)
v8pp::throw_ex(args.GetIsolate(), "MyException");
return e;
}

struct Y : X
{
static int instance_count;
Expand All @@ -71,6 +80,8 @@ int Y::instance_count = 0;

struct Z {};

struct E {};

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

auto const E_ctor = [](v8::FunctionCallbackInfo<v8::Value> const& args)
{
return create_E<Traits>(args);
};

auto const E_dtor = [](v8::Isolate* isolate, typename Traits::template object_pointer_type<E> const& obj)
{
Traits::destroy(obj);
};

v8pp::class_<E, Traits> E_class(isolate, E_dtor);
E_class
.template ctor<v8::FunctionCallbackInfo<v8::Value> const&>(E_ctor)
.set_const("konst", 42)
;

check_ex<std::runtime_error>("already wrapped class X", [isolate]()
{
v8pp::class_<X, Traits> X_class(isolate);
Expand All @@ -166,6 +193,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 +276,9 @@ 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 ctor class with exception", run_script<std::string>(context, "retError = ""; try { var e = new E(); } catch(err) { retError = err; } retError"), "MyException");
check_eq("E ctor class without exception", run_script<std::string>(context, "retError = ""; try { var e = new E(1); } catch(err) { retError = err; } retError"), "");
}

template<typename Traits>
Expand Down Expand Up @@ -370,4 +401,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 e68d34f

Please sign in to comment.