Streams: Mark promises as silent before rejecting them
This marks the `ready` and `closed` promises as silent before rejecting them. This is to prevent the inspector from breaking on exceptions whenever a stream is released. Bug: 1132506 Change-Id: If304579837e6434ff12abb8d1ffe73ef34e1220b Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3002072 Reviewed-by: Adam Rice <ricea@chromium.org> Commit-Queue: Adam Rice <ricea@chromium.org> Cr-Commit-Position: refs/heads/master@{#899837}
This commit is contained in:

committed by
Chromium LUCI CQ

parent
4e89785c34
commit
b2792108f5
AUTHORS
third_party/blink/renderer/core/streams
1
AUTHORS
1
AUTHORS
@ -483,6 +483,7 @@ Jeroen Van den Berghe <vandenberghe.jeroen@gmail.com>
|
|||||||
Jerry Lin <wahahab11@gmail.com>
|
Jerry Lin <wahahab11@gmail.com>
|
||||||
Jerry Zhang <zhj8407@gmail.com>
|
Jerry Zhang <zhj8407@gmail.com>
|
||||||
Jesper Storm Bache <jsbache@gmail.com>
|
Jesper Storm Bache <jsbache@gmail.com>
|
||||||
|
Jesper van den Ende <jespertheend@gmail.com>
|
||||||
Jesse Miller <jesse@jmiller.biz>
|
Jesse Miller <jesse@jmiller.biz>
|
||||||
Jesus Sanchez-Palencia <jesus.sanchez-palencia.fernandez.fil@intel.com>
|
Jesus Sanchez-Palencia <jesus.sanchez-palencia.fernandez.fil@intel.com>
|
||||||
Jiadong Chen <chenjiadong@huawei.com>
|
Jiadong Chen <chenjiadong@huawei.com>
|
||||||
|
@ -70,6 +70,7 @@ void ReadableStreamGenericReader::GenericRelease(
|
|||||||
// 3. If reader.[[ownerReadableStream]].[[state]] is "readable", reject
|
// 3. If reader.[[ownerReadableStream]].[[state]] is "readable", reject
|
||||||
// reader.[[closedPromise]] with a TypeError exception.
|
// reader.[[closedPromise]] with a TypeError exception.
|
||||||
if (reader->owner_readable_stream_->state_ == ReadableStream::kReadable) {
|
if (reader->owner_readable_stream_->state_ == ReadableStream::kReadable) {
|
||||||
|
reader->closed_promise_->MarkAsSilent(isolate);
|
||||||
reader->closed_promise_->Reject(
|
reader->closed_promise_->Reject(
|
||||||
script_state,
|
script_state,
|
||||||
v8::Exception::TypeError(V8String(
|
v8::Exception::TypeError(V8String(
|
||||||
@ -79,7 +80,7 @@ void ReadableStreamGenericReader::GenericRelease(
|
|||||||
} else {
|
} else {
|
||||||
// 4. Otherwise, set reader.[[closedPromise]] to a promise rejected with a
|
// 4. Otherwise, set reader.[[closedPromise]] to a promise rejected with a
|
||||||
// TypeError exception.
|
// TypeError exception.
|
||||||
reader->closed_promise_ = StreamPromiseResolver::CreateRejected(
|
reader->closed_promise_ = StreamPromiseResolver::CreateRejectedAndSilent(
|
||||||
script_state, v8::Exception::TypeError(V8String(
|
script_state, v8::Exception::TypeError(V8String(
|
||||||
isolate,
|
isolate,
|
||||||
"This readable stream reader has been released and "
|
"This readable stream reader has been released and "
|
||||||
@ -152,7 +153,7 @@ void ReadableStreamGenericReader::GenericInitialize(
|
|||||||
|
|
||||||
// b. Set reader.[[closedPromise]] to a promise rejected with stream.
|
// b. Set reader.[[closedPromise]] to a promise rejected with stream.
|
||||||
// [[storedError]].
|
// [[storedError]].
|
||||||
reader->closed_promise_ = StreamPromiseResolver::CreateRejected(
|
reader->closed_promise_ = StreamPromiseResolver::CreateRejectedAndSilent(
|
||||||
script_state, stream->GetStoredError(isolate));
|
script_state, stream->GetStoredError(isolate));
|
||||||
|
|
||||||
// c. Set reader.[[closedPromise]].[[PromiseIsHandled]] to true.
|
// c. Set reader.[[closedPromise]].[[PromiseIsHandled]] to true.
|
||||||
|
@ -32,6 +32,15 @@ StreamPromiseResolver* StreamPromiseResolver::CreateRejected(
|
|||||||
return promise;
|
return promise;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
StreamPromiseResolver* StreamPromiseResolver::CreateRejectedAndSilent(
|
||||||
|
ScriptState* script_state,
|
||||||
|
v8::Local<v8::Value> reason) {
|
||||||
|
auto* promise = MakeGarbageCollected<StreamPromiseResolver>(script_state);
|
||||||
|
promise->MarkAsSilent(script_state->GetIsolate());
|
||||||
|
promise->Reject(script_state, reason);
|
||||||
|
return promise;
|
||||||
|
}
|
||||||
|
|
||||||
StreamPromiseResolver::StreamPromiseResolver(ScriptState* script_state) {
|
StreamPromiseResolver::StreamPromiseResolver(ScriptState* script_state) {
|
||||||
v8::Local<v8::Promise::Resolver> resolver;
|
v8::Local<v8::Promise::Resolver> resolver;
|
||||||
if (v8::Promise::Resolver::New(script_state->GetContext())
|
if (v8::Promise::Resolver::New(script_state->GetContext())
|
||||||
@ -103,6 +112,14 @@ void StreamPromiseResolver::MarkAsHandled(v8::Isolate* isolate) {
|
|||||||
promise->MarkAsHandled();
|
promise->MarkAsHandled();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void StreamPromiseResolver::MarkAsSilent(v8::Isolate* isolate) {
|
||||||
|
v8::Local<v8::Promise> promise = V8Promise(isolate);
|
||||||
|
if (promise.IsEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
promise->MarkAsSilent();
|
||||||
|
}
|
||||||
|
|
||||||
v8::Promise::PromiseState StreamPromiseResolver::State(
|
v8::Promise::PromiseState StreamPromiseResolver::State(
|
||||||
v8::Isolate* isolate) const {
|
v8::Isolate* isolate) const {
|
||||||
v8::Local<v8::Promise> promise = V8Promise(isolate);
|
v8::Local<v8::Promise> promise = V8Promise(isolate);
|
||||||
|
@ -46,6 +46,12 @@ class CORE_EXPORT StreamPromiseResolver final
|
|||||||
static StreamPromiseResolver* CreateRejected(ScriptState*,
|
static StreamPromiseResolver* CreateRejected(ScriptState*,
|
||||||
v8::Local<v8::Value> reason);
|
v8::Local<v8::Value> reason);
|
||||||
|
|
||||||
|
// Similar to CreateRejected but marks the promise as silent before rejecting.
|
||||||
|
// https://crbug.com/1132506
|
||||||
|
static StreamPromiseResolver* CreateRejectedAndSilent(
|
||||||
|
ScriptState*,
|
||||||
|
v8::Local<v8::Value> reason);
|
||||||
|
|
||||||
// Creates an initialised promise.
|
// Creates an initialised promise.
|
||||||
explicit StreamPromiseResolver(ScriptState*);
|
explicit StreamPromiseResolver(ScriptState*);
|
||||||
|
|
||||||
@ -70,6 +76,10 @@ class CORE_EXPORT StreamPromiseResolver final
|
|||||||
// an unhandled rejection.
|
// an unhandled rejection.
|
||||||
void MarkAsHandled(v8::Isolate*);
|
void MarkAsHandled(v8::Isolate*);
|
||||||
|
|
||||||
|
// Marks the promise as silent so that it doesn't pause the debugger when it
|
||||||
|
// rejects.
|
||||||
|
void MarkAsSilent(v8::Isolate*);
|
||||||
|
|
||||||
// Returns the state of the promise, one of pending, fulfilled or rejected.
|
// Returns the state of the promise, one of pending, fulfilled or rejected.
|
||||||
v8::Promise::PromiseState State(v8::Isolate*) const;
|
v8::Promise::PromiseState State(v8::Isolate*) const;
|
||||||
|
|
||||||
|
@ -92,7 +92,7 @@ WritableStreamDefaultWriter::WritableStreamDefaultWriter(
|
|||||||
case WritableStream::kErroring: {
|
case WritableStream::kErroring: {
|
||||||
// a. Set this.[[readyPromise]] to a promise rejected with
|
// a. Set this.[[readyPromise]] to a promise rejected with
|
||||||
// stream.[[storedError]].
|
// stream.[[storedError]].
|
||||||
ready_promise_ = StreamPromiseResolver::CreateRejected(
|
ready_promise_ = StreamPromiseResolver::CreateRejectedAndSilent(
|
||||||
script_state, stream->GetStoredError(isolate));
|
script_state, stream->GetStoredError(isolate));
|
||||||
|
|
||||||
// b. Set this.[[readyPromise]].[[PromiseIsHandled]] to true.
|
// b. Set this.[[readyPromise]].[[PromiseIsHandled]] to true.
|
||||||
@ -127,16 +127,16 @@ WritableStreamDefaultWriter::WritableStreamDefaultWriter(
|
|||||||
|
|
||||||
// c. Set this.[[readyPromise]] to a promise rejected with
|
// c. Set this.[[readyPromise]] to a promise rejected with
|
||||||
// storedError.
|
// storedError.
|
||||||
ready_promise_ =
|
ready_promise_ = StreamPromiseResolver::CreateRejectedAndSilent(
|
||||||
StreamPromiseResolver::CreateRejected(script_state, stored_error);
|
script_state, stored_error);
|
||||||
|
|
||||||
// d. Set this.[[readyPromise]].[[PromiseIsHandled]] to true.
|
// d. Set this.[[readyPromise]].[[PromiseIsHandled]] to true.
|
||||||
ready_promise_->MarkAsHandled(isolate);
|
ready_promise_->MarkAsHandled(isolate);
|
||||||
|
|
||||||
// e. Set this.[[closedPromise]] to a promise rejected with
|
// e. Set this.[[closedPromise]] to a promise rejected with
|
||||||
// storedError.
|
// storedError.
|
||||||
closed_promise_ =
|
closed_promise_ = StreamPromiseResolver::CreateRejectedAndSilent(
|
||||||
StreamPromiseResolver::CreateRejected(script_state, stored_error);
|
script_state, stored_error);
|
||||||
|
|
||||||
// f. Set this.[[closedPromise]].[[PromiseIsHandled]] to true.
|
// f. Set this.[[closedPromise]].[[PromiseIsHandled]] to true.
|
||||||
closed_promise_->MarkAsHandled(isolate);
|
closed_promise_->MarkAsHandled(isolate);
|
||||||
@ -284,12 +284,13 @@ void WritableStreamDefaultWriter::EnsureReadyPromiseRejected(
|
|||||||
// 1. If writer.[[readyPromise]].[[PromiseState]] is "pending", reject
|
// 1. If writer.[[readyPromise]].[[PromiseState]] is "pending", reject
|
||||||
// writer.[[readyPromise]] with error.
|
// writer.[[readyPromise]] with error.
|
||||||
if (!writer->ready_promise_->IsSettled()) {
|
if (!writer->ready_promise_->IsSettled()) {
|
||||||
|
writer->ready_promise_->MarkAsSilent(isolate);
|
||||||
writer->ready_promise_->Reject(script_state, error);
|
writer->ready_promise_->Reject(script_state, error);
|
||||||
} else {
|
} else {
|
||||||
// 2. Otherwise, set writer.[[readyPromise]] to a promise rejected with
|
// 2. Otherwise, set writer.[[readyPromise]] to a promise rejected with
|
||||||
// error.
|
// error.
|
||||||
writer->ready_promise_ =
|
writer->ready_promise_ =
|
||||||
StreamPromiseResolver::CreateRejected(script_state, error);
|
StreamPromiseResolver::CreateRejectedAndSilent(script_state, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. Set writer.[[readyPromise]].[[PromiseIsHandled]] to true.
|
// 3. Set writer.[[readyPromise]].[[PromiseIsHandled]] to true.
|
||||||
@ -517,12 +518,13 @@ void WritableStreamDefaultWriter::EnsureClosedPromiseRejected(
|
|||||||
// 1. If writer.[[closedPromise]].[[PromiseState]] is "pending", reject
|
// 1. If writer.[[closedPromise]].[[PromiseState]] is "pending", reject
|
||||||
// writer.[[closedPromise]] with error.
|
// writer.[[closedPromise]] with error.
|
||||||
if (!writer->closed_promise_->IsSettled()) {
|
if (!writer->closed_promise_->IsSettled()) {
|
||||||
|
writer->closed_promise_->MarkAsSilent(isolate);
|
||||||
writer->closed_promise_->Reject(script_state, error);
|
writer->closed_promise_->Reject(script_state, error);
|
||||||
} else {
|
} else {
|
||||||
// 2. Otherwise, set writer.[[closedPromise]] to a promise rejected with
|
// 2. Otherwise, set writer.[[closedPromise]] to a promise rejected with
|
||||||
// error.
|
// error.
|
||||||
writer->closed_promise_ =
|
writer->closed_promise_ =
|
||||||
StreamPromiseResolver::CreateRejected(script_state, error);
|
StreamPromiseResolver::CreateRejectedAndSilent(script_state, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. Set writer.[[closedPromise]].[[PromiseIsHandled]] to true.
|
// 3. Set writer.[[closedPromise]].[[PromiseIsHandled]] to true.
|
||||||
|
Reference in New Issue
Block a user