Bug 1504464 - Part 2: Mark reader.[[closedPromise]] as handled in reader.releaseLock(). r=jwalden

In this case, it's likely the user doesn't see this as an error at all.

Differential Revision: https://phabricator.services.mozilla.com/D14497

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Jason Orendorff 2019-01-14 20:31:29 +00:00
parent 0e778e8714
commit 176572ef97
2 changed files with 47 additions and 8 deletions

View File

@ -2119,19 +2119,20 @@ static MOZ_MUST_USE bool ReadableStreamReaderGenericRelease(
// Step 3: If reader.[[ownerReadableStream]].[[state]] is "readable", reject
// reader.[[closedPromise]] with a TypeError exception.
Rooted<PromiseObject*> unwrappedClosedPromise(cx);
if (unwrappedStream->readable()) {
Rooted<PromiseObject*> closedPromise(
cx, UnwrapInternalSlot<PromiseObject>(
cx, unwrappedReader, ReadableStreamReader::Slot_ClosedPromise));
if (!closedPromise) {
unwrappedClosedPromise =
UnwrapInternalSlot<PromiseObject>(
cx, unwrappedReader, ReadableStreamReader::Slot_ClosedPromise);
if (!unwrappedClosedPromise) {
return false;
}
AutoRealm ar(cx, closedPromise);
AutoRealm ar(cx, unwrappedClosedPromise);
if (!cx->compartment()->wrap(cx, &exn)) {
return false;
}
if (!PromiseObject::reject(cx, closedPromise, exn)) {
if (!PromiseObject::reject(cx, unwrappedClosedPromise, exn)) {
return false;
}
} else {
@ -2141,6 +2142,7 @@ static MOZ_MUST_USE bool ReadableStreamReaderGenericRelease(
if (!closedPromise) {
return false;
}
unwrappedClosedPromise = &closedPromise->as<PromiseObject>();
AutoRealm ar(cx, unwrappedReader);
if (!cx->compartment()->wrap(cx, &closedPromise)) {
@ -2149,10 +2151,14 @@ static MOZ_MUST_USE bool ReadableStreamReaderGenericRelease(
unwrappedReader->setClosedPromise(closedPromise);
}
// Step 5: Set reader.[[ownerReadableStream]].[[reader]] to undefined.
// Step 5: Set reader.[[closedPromise]].[[PromiseIsHandled]] to true.
unwrappedClosedPromise->setHandled();
cx->runtime()->removeUnhandledRejectedPromise(cx, unwrappedClosedPromise);
// Step 6: Set reader.[[ownerReadableStream]].[[reader]] to undefined.
unwrappedStream->clearReader();
// Step 6: Set reader.[[ownerReadableStream]] to undefined.
// Step 7: Set reader.[[ownerReadableStream]] to undefined.
unwrappedReader->clearStream();
return true;

View File

@ -0,0 +1,33 @@
// Releasing a reader should not result in a promise being tracked as
// unhandled.
function test(readable) {
// Create an errored stream.
let controller;
let stream = new ReadableStream({
start(c) {
controller = c;
}
});
drainJobQueue();
// Track promises.
let status = new Map;
setPromiseRejectionTrackerCallback((p, x) => { status.set(p, x); });
// Per Streams spec 3.7.5 step 5, this creates a rejected promise
// (reader.closed) but marks it as handled.
let reader = stream.getReader();
if (!readable) {
controller.close();
}
reader.releaseLock();
// Check that the promise's status is not 0 (unhandled);
// it may be either 1 (handled) or undefined (never tracked).
let result = status.get(reader.closed);
assertEq(result === 1 || result === undefined, true);
}
test(true);
test(false);