mirror of
https://github.com/servo/servo.git
synced 2025-08-06 06:00:15 +01:00
fix setting and propagating of abort reason
Signed-off-by: gterzian <2792687+gterzian@users.noreply.github.com>
This commit is contained in:
parent
99bbef833a
commit
2f2e962ae0
3 changed files with 43 additions and 5 deletions
|
@ -26,7 +26,7 @@ impl AbortController {
|
||||||
/// <https://dom.spec.whatwg.org/#dom-abortcontroller-abortcontroller>
|
/// <https://dom.spec.whatwg.org/#dom-abortcontroller-abortcontroller>
|
||||||
fn new_inherited(signal: &AbortSignal) -> AbortController {
|
fn new_inherited(signal: &AbortSignal) -> AbortController {
|
||||||
// Note: continuation of the constructor steps.
|
// Note: continuation of the constructor steps.
|
||||||
|
|
||||||
// Set this’s signal to signal.
|
// Set this’s signal to signal.
|
||||||
AbortController {
|
AbortController {
|
||||||
reflector_: Reflector::new(),
|
reflector_: Reflector::new(),
|
||||||
|
|
|
@ -91,7 +91,7 @@ impl AbortSignal {
|
||||||
let abort_reason = reason.get();
|
let abort_reason = reason.get();
|
||||||
|
|
||||||
// Set signal’s abort reason to reason if it is given;
|
// Set signal’s abort reason to reason if it is given;
|
||||||
if !abort_reason.is_undefined() {
|
if !abort_reason.is_null() {
|
||||||
self.abort_reason.set(abort_reason);
|
self.abort_reason.set(abort_reason);
|
||||||
} else {
|
} else {
|
||||||
// otherwise to a new "AbortError" DOMException.
|
// otherwise to a new "AbortError" DOMException.
|
||||||
|
@ -133,6 +133,17 @@ impl AbortSignal {
|
||||||
) {
|
) {
|
||||||
match algorithm {
|
match algorithm {
|
||||||
AbortAlgorithm::StreamPiping(pipe) => {
|
AbortAlgorithm::StreamPiping(pipe) => {
|
||||||
|
// Note: the streams spec says to "If signal is aborted, perform abortAlgorithm",
|
||||||
|
// which bypasses the signal abort concept,
|
||||||
|
// and bypasses the steps in that concept that set the default reason
|
||||||
|
// (see "otherwise to a new "AbortError" DOMException.")
|
||||||
|
// So we add it here even though it remains unspecified,
|
||||||
|
// because the `/stream/piping/abort.any.js` test rely on this mechanism.
|
||||||
|
if self.abort_reason.get().is_undefined() {
|
||||||
|
rooted!(in(*cx) let mut rooted_error = UndefinedValue());
|
||||||
|
Error::Abort.to_jsval(cx, &global, rooted_error.handle_mut(), can_gc);
|
||||||
|
self.abort_reason.set(rooted_error.get())
|
||||||
|
}
|
||||||
rooted!(in(*cx) let mut reason = UndefinedValue());
|
rooted!(in(*cx) let mut reason = UndefinedValue());
|
||||||
reason.set(self.abort_reason.get());
|
reason.set(self.abort_reason.get());
|
||||||
pipe.abort_with_reason(cx, global, reason.handle(), realm, can_gc);
|
pipe.abort_with_reason(cx, global, reason.handle(), realm, can_gc);
|
||||||
|
@ -168,7 +179,7 @@ impl AbortSignal {
|
||||||
/// <https://dom.spec.whatwg.org/#abortsignal-aborted>
|
/// <https://dom.spec.whatwg.org/#abortsignal-aborted>
|
||||||
pub(crate) fn aborted(&self) -> bool {
|
pub(crate) fn aborted(&self) -> bool {
|
||||||
// An AbortSignal object is aborted when its abort reason is not undefined.
|
// An AbortSignal object is aborted when its abort reason is not undefined.
|
||||||
!self.abort_reason.get().is_undefined()
|
!self.abort_reason.get().is_null()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -182,6 +182,15 @@ impl PipeTo {
|
||||||
// Let error be signal’s abort reason.
|
// Let error be signal’s abort reason.
|
||||||
self.abort_reason.set(error.get());
|
self.abort_reason.set(error.get());
|
||||||
|
|
||||||
|
// Note: setting the error now,
|
||||||
|
// will result in a rejection of the pipe promise, with this error.
|
||||||
|
// Unless any shutdown action raise their own error,
|
||||||
|
// in which case this error will be overwritten by the shutdown action error.
|
||||||
|
self.shutdown_error.set(error.get());
|
||||||
|
|
||||||
|
rooted!(in(*cx) let mut error = self.shutdown_error.get());
|
||||||
|
assert!(!error.is_undefined());
|
||||||
|
|
||||||
// Let actions be an empty ordered set.
|
// Let actions be an empty ordered set.
|
||||||
// Note: the actions are defined, and performed, inside `shutdown_with_an_action`.
|
// Note: the actions are defined, and performed, inside `shutdown_with_an_action`.
|
||||||
|
|
||||||
|
@ -329,10 +338,28 @@ impl Callback for PipeTo {
|
||||||
|
|
||||||
// Finalize, passing along error if it was given.
|
// Finalize, passing along error if it was given.
|
||||||
if !result.is_undefined() {
|
if !result.is_undefined() {
|
||||||
// All actions either resolve with undefined,
|
// Most actions either resolve with undefined,
|
||||||
// or reject with an error,
|
// or reject with an error,
|
||||||
// and the error should be used when finalizing.
|
// and the error should be used when finalizing.
|
||||||
self.shutdown_error.set(result.get());
|
// One exception is the `Abort` action,
|
||||||
|
// which resolves with a list of undefined values.
|
||||||
|
rooted!(in(*cx) let object = result.to_object());
|
||||||
|
rooted!(in(*cx) let mut done = UndefinedValue());
|
||||||
|
let property = unsafe {
|
||||||
|
get_dictionary_property(
|
||||||
|
*cx,
|
||||||
|
object.handle(),
|
||||||
|
"0",
|
||||||
|
done.handle_mut(),
|
||||||
|
can_gc,
|
||||||
|
)
|
||||||
|
};
|
||||||
|
if let Ok(false) = property {
|
||||||
|
// If `result` isn't undefined, or a list,
|
||||||
|
// then it is an error
|
||||||
|
// and should overwrite the current shutdown error.
|
||||||
|
self.shutdown_error.set(result.get());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
self.finalize(cx, &global, can_gc);
|
self.finalize(cx, &global, can_gc);
|
||||||
},
|
},
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue