V8 - Node C++ Addon - Throwing Exception in a ConstructCall causes "FATAL ERROR: v8::ToLocalChecked Empty MaybeLocal." - How to fail a constructor?

V8 - Node C++ Addon - Throwing Exception in a ConstructCall causes "FATAL ERROR: v8::ToLocalChecked Empty MaybeLocal." - How to fail a constructor?

基本上我想检查传递给构造函数参数并抛出一个异常当参数不满足特定条件时。

我的 C++ 对象继承了 node::ObjectWrap.

  v8::Persistent<v8::Function> SomeKlass::constructor;

FunctionTemplate用于在JavaScript中设置构造函数

  void SomeKlass::Init(v8::Local<v8::Object> exports) {

    v8::Isolate* isolate = exports->GetIsolate();

    v8::Local<v8::FunctionTemplate> tpl = v8::FunctionTemplate::New(isolate, New);

    /* ... */

    constructor.Reset(isolate, tpl->GetFunction());

    exports->Set(v8::String::NewFromUtf8(isolate, "SomeKlass"), tpl->GetFunction());

  }

当 New 是构造调用时抛出异常会产生运行时致命错误。

然而,在 'function call'(没有新的 keyward)中抛出相同的异常工作正常。

  void SomeKlass::New(const v8::FunctionCallbackInfo<v8::Value>& args) {

    v8::Isolate *isolate = args.GetIsolate();

    if (args.IsConstructCall()) {

      SomeKlass* obj = new SomeKlass();

      if (...) {
        // set args.This() to undefined.

        /* THIS CAUSES "FATAL ERROR: v8::ToLocalChecked Empty MaybeLocal."
         *
         * isolate->ThrowException(v8::Exception::TypeError(
         *   v8::String::NewFromUtf8(isolate, "Error"))); 
         */

        return;
      }

      obj->Wrap(args.This());

      args.GetReturnValue().Set(args.This());

    } else {

      /* Exceptions do not produce a FATAL ERROR here. */

    }

  }

}

使构造函数失败的正确方法是什么?

节点版本:6.10.3 或 8.1.4

v8 版本:5.1.281 或 5.8.282

我发现为什么在 constructor 中抛出 exceptions 会导致崩溃。

因为我在另一个地方调用NewObject

template <typename T>//;
static v8::Local<v8::Object> NewObject(const T &args) {
  auto isolate = args.GetIsolate();

  auto context = isolate->GetCurrentContext();
  auto cons = v8::Local<v8::Function>::New(isolate, Klass::constructor);
  return cons->NewInstance(context).ToLocalChecked();
}

失败的构造函数生成一个空对象。

从中调用 ToLocalChecked() 导致 "FATAL ERROR: v8::ToLocalChecked Empty MaybeLocal.",这是意料之中的,也是有道理的。