关于unhandled promise reject 处理闪崩的问题

/**

  • Bug in v8 stacktrace:
  • “handlerAddedAfterPromiseRejected” event is triggered if a resolve handler is added.
  • But if no reject handler is added, then “unhandledRejectedPromise” exception will be called again, but the stacktrace this time become empty
  • LastStackTrace is used to store it.
    */
    void ScriptEngine::pushPromiseExeception(const v8::Localv8::Promise &promise, const char *event, const char *stackTrace) {
    using element_type = decltype(_promiseArray)::value_type;
    element_type *current;

auto itr = std::find_if(_promiseArray.begin(), _promiseArray.end(), [&](const auto &e) -> bool {
return std::get<0>(e)->Get(_isolate) == promise;
});

if (itr == _promiseArray.end()) { // Not found, create one
_promiseArray.emplace_back(std::make_unique<v8::Persistentv8::Promise>(), ccstd::vector{});
std::get<0>(_promiseArray.back())->Reset(_isolate, promise);
current = &_promiseArray.back();
} else {
current = &(*itr);
}

auto &exceptions = std::get<1>(*current);
if (std::strcmp(event, “handlerAddedAfterPromiseRejected”) == 0) {
for (int i = 0; i < exceptions.size(); i++) {
if (exceptions[i].event == “unhandledRejectedPromise”) {
_lastStackTrace = exceptions[i].stackTrace;
exceptions.erase(exceptions.begin() + i);
return;
}
}
}
exceptions.push_back(PromiseExceptionMsg{event, stackTrace});
}

void ScriptEngine::handlePromiseExceptions() {
if (_promiseArray.empty()) {
return;
}
for (auto &exceptionsPair : _promiseArray) {
auto &exceptionVector = std::get<1>(exceptionsPair);
for (const auto &exceptions : exceptionVector) {
getInstance()->callExceptionCallback("", exceptions.event.c_str(), exceptions.stackTrace.c_str());
}
std::get<0>(exceptionsPair).get()->Reset();
}
_promiseArray.clear();
_lastStackTrace.clear();
}

我感觉把v8::Promise存到下一个tick去处理这种方式不合适,因为promise有可能被回收,这句话有可能会造成崩溃,std::get<0>(exceptionsPair).get()->Reset();
我看没有必要保存Promise,这个的用途只是用来做比较,因此保存它的id就可以了。

1赞