src: yield empty maybes for failed AsyncWrap::MakeCallback calls
Use an empty `MaybeLocal<Value>` as the return value for `AsyncWrap::MakeCallback()` if an exception occurred, regardless of `MakeCallback` depth. Unfortunately, the public API can not make this switch without a breaking change (and possibly some kind of deprecation/renaming). PR-URL: https://github.com/nodejs/node/pull/22078 Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com> Reviewed-By: Ujjwal Sharma <usharma1998@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Jon Moss <me@jonathanmoss.me>
This commit is contained in:
parent
801c490033
commit
45d0b4a300
@ -87,7 +87,7 @@ void InternalCallbackScope::Close() {
|
||||
AsyncWrap::EmitAfter(env_, async_context_.async_id);
|
||||
}
|
||||
|
||||
if (IsInnerMakeCallback()) {
|
||||
if (env_->makecallback_depth() > 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -218,8 +218,8 @@ inline Environment::AsyncCallbackScope::~AsyncCallbackScope() {
|
||||
env_->makecallback_cntr_--;
|
||||
}
|
||||
|
||||
inline bool Environment::AsyncCallbackScope::in_makecallback() const {
|
||||
return env_->makecallback_cntr_ > 1;
|
||||
inline size_t Environment::makecallback_depth() const {
|
||||
return makecallback_cntr_;
|
||||
}
|
||||
|
||||
inline Environment::ImmediateInfo::ImmediateInfo(v8::Isolate* isolate)
|
||||
|
@ -499,7 +499,6 @@ class Environment {
|
||||
AsyncCallbackScope() = delete;
|
||||
explicit AsyncCallbackScope(Environment* env);
|
||||
~AsyncCallbackScope();
|
||||
inline bool in_makecallback() const;
|
||||
|
||||
private:
|
||||
Environment* env_;
|
||||
@ -507,6 +506,8 @@ class Environment {
|
||||
DISALLOW_COPY_AND_ASSIGN(AsyncCallbackScope);
|
||||
};
|
||||
|
||||
inline size_t makecallback_depth() const;
|
||||
|
||||
class ImmediateInfo {
|
||||
public:
|
||||
inline AliasedBuffer<uint32_t, v8::Uint32Array>& fields();
|
||||
|
18
src/node.cc
18
src/node.cc
@ -757,7 +757,7 @@ MaybeLocal<Value> InternalMakeCallback(Environment* env,
|
||||
CHECK(!recv.IsEmpty());
|
||||
InternalCallbackScope scope(env, recv, asyncContext);
|
||||
if (scope.Failed()) {
|
||||
return Undefined(env->isolate());
|
||||
return MaybeLocal<Value>();
|
||||
}
|
||||
|
||||
Local<Function> domain_cb = env->domain_callback();
|
||||
@ -772,15 +772,13 @@ MaybeLocal<Value> InternalMakeCallback(Environment* env,
|
||||
}
|
||||
|
||||
if (ret.IsEmpty()) {
|
||||
// NOTE: For backwards compatibility with public API we return Undefined()
|
||||
// if the top level call threw.
|
||||
scope.MarkAsFailed();
|
||||
return scope.IsInnerMakeCallback() ? ret : Undefined(env->isolate());
|
||||
return MaybeLocal<Value>();
|
||||
}
|
||||
|
||||
scope.Close();
|
||||
if (scope.Failed()) {
|
||||
return Undefined(env->isolate());
|
||||
return MaybeLocal<Value>();
|
||||
}
|
||||
|
||||
return ret;
|
||||
@ -832,8 +830,14 @@ MaybeLocal<Value> MakeCallback(Isolate* isolate,
|
||||
// the two contexts need not be the same.
|
||||
Environment* env = Environment::GetCurrent(callback->CreationContext());
|
||||
Context::Scope context_scope(env->context());
|
||||
return InternalMakeCallback(env, recv, callback,
|
||||
argc, argv, asyncContext);
|
||||
MaybeLocal<Value> ret = InternalMakeCallback(env, recv, callback,
|
||||
argc, argv, asyncContext);
|
||||
if (ret.IsEmpty() && env->makecallback_depth() == 0) {
|
||||
// This is only for legacy compatiblity and we may want to look into
|
||||
// removing/adjusting it.
|
||||
return Undefined(env->isolate());
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
@ -543,9 +543,6 @@ class InternalCallbackScope {
|
||||
|
||||
inline bool Failed() const { return failed_; }
|
||||
inline void MarkAsFailed() { failed_ = true; }
|
||||
inline bool IsInnerMakeCallback() const {
|
||||
return callback_scope_.in_makecallback();
|
||||
}
|
||||
|
||||
private:
|
||||
Environment* env_;
|
||||
|
Loading…
x
Reference in New Issue
Block a user