V8 - 节点C ++插件 - 在ConstructCall中抛出异常导致“致命错误:v8 :: ToLocalChecked清空MaybeLocal”。 - 如何使构造函数失败?

时间:2017-07-16 18:46:21

标签: c++ node.js v8 embedded-v8

基本上我想检查传递给构造函数参数,并在参数不符合某些条件时抛出异常

我的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是构造调用时抛出异常会产生运行时致命错误。

但是,在'函数调用'中抛出相同的异常(没有新的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

1 个答案:

答案 0 :(得分:0)

我发现为什么在构造函数中抛出异常会导致崩溃。

这是因为我在其他地方调用 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()导致&#34;致命错误:v8 :: ToLocalChecked清空MaybeLocal。&#34;,这是预期的并且有意义。