@@ -18,15 +18,18 @@ using v8::CFunction;
1818using v8::Context;
1919using v8::DictionaryTemplate;
2020using v8::External;
21+ using v8::Function;
2122using v8::FunctionCallbackInfo;
2223using v8::IndexFilter;
2324using v8::Integer;
2425using v8::Isolate;
2526using v8::KeyCollectionMode;
27+ using v8::kPromiseHandlerAddedAfterReject ;
2628using v8::Local;
2729using v8::LocalVector;
2830using v8::MaybeLocal;
2931using v8::Name;
32+ using v8::Number;
3033using v8::Object;
3134using v8::ObjectTemplate;
3235using v8::ONLY_CONFIGURABLE ;
@@ -467,6 +470,26 @@ void MarkPromiseAsHandled(const FunctionCallbackInfo<Value>& args) {
467470 Local<Promise> promise = args[0 ].As <Promise>();
468471 promise->MarkAsHandled ();
469472 promise->MarkAsSilent ();
473+
474+ // If the promise is already rejected, then it may have already been
475+ // reported to the unhandled rejection handler. Marking it as handled
476+ // above does not trigger the v8 callback that updates it's status.
477+ // So to avoid the notification we call out manually.
478+ if (promise->State () == v8::Promise::kRejected ) {
479+ Environment* env = Environment::GetCurrent (args);
480+ Local<Function> callback = env->promise_reject_callback ();
481+ CHECK (!callback.IsEmpty ());
482+
483+ Local<Value> type =
484+ Number::New (env->isolate (), kPromiseHandlerAddedAfterReject );
485+ Local<Value> vargs[] = {type, promise, Undefined (env->isolate ())};
486+
487+ USE (callback->Call (
488+ env->context (), Undefined (env->isolate ()), arraysize (vargs), vargs));
489+
490+ // Note that if callback->Call throws here, we go ahead and let that
491+ // propagate.
492+ }
470493}
471494
472495void RegisterExternalReferences (ExternalReferenceRegistry* registry) {
0 commit comments