Bug 1634264 - Reject MozPromise when DomPromiseListener is deleted. r=mattwoodrow

We remove the assertion that the error code was NS_OK, as users of FromDomPromise assert it must be a failure.

Differential Revision: https://phabricator.services.mozilla.com/D75737
This commit is contained in:
Jean-Yves Avenard 2020-05-18 22:16:38 +00:00
parent 27a590bd9e
commit dfb2061bb1
3 changed files with 28 additions and 21 deletions

View File

@ -18,12 +18,18 @@ DomPromiseListener::DomPromiseListener(dom::Promise* aDOMPromise) {
}
DomPromiseListener::DomPromiseListener(dom::Promise* aDOMPromise,
CallbackType&& aResolve,
CallbackType&& aReject)
CallbackTypeResolved&& aResolve,
CallbackTypeRejected&& aReject)
: mResolve(Some(std::move(aResolve))), mReject(Some(std::move(aReject))) {
aDOMPromise->AppendNativeHandler(this);
}
DomPromiseListener::~DomPromiseListener() {
if (mReject) {
(*mReject)(NS_BINDING_ABORTED);
}
}
void DomPromiseListener::ResolvedCallback(JSContext* aCx,
JS::Handle<JS::Value> aValue) {
if (mResolve) {
@ -37,15 +43,21 @@ void DomPromiseListener::ResolvedCallback(JSContext* aCx,
void DomPromiseListener::RejectedCallback(JSContext* aCx,
JS::Handle<JS::Value> aValue) {
if (mReject) {
(*mReject)(aCx, aValue);
nsresult errorCode;
if (!aValue.isInt32()) {
errorCode = NS_ERROR_DOM_NOT_NUMBER_ERR;
} else {
errorCode = nsresult(aValue.toInt32());
}
(*mReject)(errorCode);
}
// Let's clear the lambdas in case we have a cycle to ourselves.
mResolve.reset();
mReject.reset();
}
void DomPromiseListener::SetResolvers(CallbackType&& aResolve,
CallbackType&& aReject) {
void DomPromiseListener::SetResolvers(CallbackTypeResolved&& aResolve,
CallbackTypeRejected&& aReject) {
mResolve = Some(std::move(aResolve));
mReject = Some(std::move(aReject));
}

View File

@ -41,19 +41,22 @@ class DomPromiseListener final : public PromiseNativeHandler {
NS_DECL_ISUPPORTS
public:
using CallbackType = std::function<void(JSContext*, JS::Handle<JS::Value>)>;
using CallbackTypeResolved =
std::function<void(JSContext*, JS::Handle<JS::Value>)>;
using CallbackTypeRejected = std::function<void(nsresult)>;
explicit DomPromiseListener(Promise* aDOMPromise);
DomPromiseListener(Promise* aDOMPromise, CallbackType&& aResolve,
CallbackType&& aReject);
void SetResolvers(CallbackType&& aResolve, CallbackType&& aReject);
DomPromiseListener(Promise* aDOMPromise, CallbackTypeResolved&& aResolve,
CallbackTypeRejected&& aReject);
void SetResolvers(CallbackTypeResolved&& aResolve,
CallbackTypeRejected&& aReject);
void ResolvedCallback(JSContext* aCx, JS::Handle<JS::Value> aValue) override;
void RejectedCallback(JSContext* aCx, JS::Handle<JS::Value> aValue) override;
private:
~DomPromiseListener() = default;
Maybe<CallbackType> mResolve;
Maybe<CallbackType> mReject;
~DomPromiseListener();
Maybe<CallbackTypeResolved> mResolve;
Maybe<CallbackTypeRejected> mReject;
};
} // namespace dom

View File

@ -38,15 +38,7 @@ MozPromise<ResolveValueT, RejectValueT, IsExclusive>::FromDomPromise(
}
p->Resolve(value, __func__);
},
[p](JSContext* aCx, JS::Handle<JS::Value> aValue) {
if (!aValue.isInt32()) {
p->Reject(NS_ERROR_DOM_NOT_NUMBER_ERR, __func__);
return;
}
nsresult rv = nsresult(aValue.toInt32());
MOZ_ASSERT(NS_SUCCEEDED(rv));
p->Reject(rv, __func__);
});
[p](nsresult aError) { p->Reject(aError, __func__); });
return p;
}