refactor: add CanGc as argument to Promise::reject_error (#35646)

Signed-off-by: Yerkebulan Tulibergenov <yerkebulan@gmail.com>
This commit is contained in:
Yerkebulan Tulibergenov 2025-02-25 02:12:58 -08:00 committed by GitHub
parent c844ed232a
commit 38b71087bd
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
43 changed files with 323 additions and 249 deletions

View file

@ -645,7 +645,7 @@ impl ConsumeBodyPromiseHandler {
},
};
},
Err(err) => self.result_promise.reject_error(err),
Err(err) => self.result_promise.reject_error(err, can_gc),
}
}
}
@ -665,7 +665,7 @@ impl Callback for ConsumeBodyPromiseHandler {
Err(err) => {
stream.stop_reading(can_gc);
// When read is fulfilled with a value that doesn't matches with neither of the above patterns.
return self.result_promise.reject_error(err);
return self.result_promise.reject_error(err, can_gc);
},
};
@ -678,7 +678,7 @@ impl Callback for ConsumeBodyPromiseHandler {
Err(err) => {
stream.stop_reading(can_gc);
// When read is fulfilled with a value that matches with neither of the above patterns
return self.result_promise.reject_error(err);
return self.result_promise.reject_error(err, can_gc);
},
};
@ -734,9 +734,10 @@ pub(crate) fn consume_body<T: BodyMixin + DomObject>(
// Step 1
if object.is_disturbed() || object.is_locked() {
promise.reject_error(Error::Type(
"The body's stream is disturbed or locked".to_string(),
));
promise.reject_error(
Error::Type("The body's stream is disturbed or locked".to_string()),
can_gc,
);
return promise;
}
@ -770,9 +771,10 @@ fn consume_body_with_promise<T: BodyMixin + DomObject>(
// Step 3.
if stream.acquire_default_reader(can_gc).is_err() {
return promise.reject_error(Error::Type(
"The response's stream is disturbed or locked".to_string(),
));
return promise.reject_error(
Error::Type("The response's stream is disturbed or locked".to_string()),
can_gc,
);
}
// Step 4, read all the bytes.

View file

@ -146,7 +146,7 @@ impl AudioContextMethods<crate::DomTypeHolder> for AudioContext {
// Step 2.
if self.context.control_thread_state() == ProcessingState::Closed {
promise.reject_error(Error::InvalidState);
promise.reject_error(Error::InvalidState, can_gc);
return promise;
}
@ -186,7 +186,7 @@ impl AudioContextMethods<crate::DomTypeHolder> for AudioContext {
.dom_manipulation_task_source()
.queue(task!(suspend_error: move || {
let promise = trusted_promise.root();
promise.reject_error(Error::Type("Something went wrong".to_owned()));
promise.reject_error(Error::Type("Something went wrong".to_owned()), CanGc::note());
}));
},
};
@ -202,7 +202,7 @@ impl AudioContextMethods<crate::DomTypeHolder> for AudioContext {
// Step 2.
if self.context.control_thread_state() == ProcessingState::Closed {
promise.reject_error(Error::InvalidState);
promise.reject_error(Error::InvalidState, can_gc);
return promise;
}
@ -242,7 +242,7 @@ impl AudioContextMethods<crate::DomTypeHolder> for AudioContext {
.dom_manipulation_task_source()
.queue(task!(suspend_error: move || {
let promise = trusted_promise.root();
promise.reject_error(Error::Type("Something went wrong".to_owned()));
promise.reject_error(Error::Type("Something went wrong".to_owned()), CanGc::note());
}));
},
};

View file

@ -212,7 +212,7 @@ impl BaseAudioContext {
for promise in &*promises {
match result {
Ok(ref value) => promise.resolve_native(value, CanGc::note()),
Err(ref error) => promise.reject_error(error.clone()),
Err(ref error) => promise.reject_error(error.clone(), CanGc::note()),
}
}
}
@ -292,7 +292,7 @@ impl BaseAudioContextMethods<crate::DomTypeHolder> for BaseAudioContext {
// Step 2.
if self.audio_context_impl.lock().unwrap().state() == ProcessingState::Closed {
promise.reject_error(Error::InvalidState);
promise.reject_error(Error::InvalidState, can_gc);
return promise;
}
@ -564,7 +564,7 @@ impl BaseAudioContextMethods<crate::DomTypeHolder> for BaseAudioContext {
ExceptionHandling::Report);
}
let error = format!("Audio decode error {:?}", error);
resolver.promise.reject_error(Error::Type(error));
resolver.promise.reject_error(Error::Type(error), CanGc::note());
}));
})
.build();
@ -574,7 +574,7 @@ impl BaseAudioContextMethods<crate::DomTypeHolder> for BaseAudioContext {
.decode_audio_data(audio_data, callbacks);
} else {
// Step 3.
promise.reject_error(Error::DataClone);
promise.reject_error(Error::DataClone, can_gc);
return promise;
}

View file

@ -139,7 +139,7 @@ impl TrustedPromise {
let this = self;
task!(reject_promise: move || {
debug!("Rejecting promise.");
this.root().reject_error(error);
this.root().reject_error(error, CanGc::note());
})
}

View file

@ -259,7 +259,7 @@ impl BlobMethods<crate::DomTypeHolder> for Blob {
promise.resolve_native(&text, CanGc::note());
},
Err(e) => {
promise.reject_error(e);
promise.reject_error(e, CanGc::note());
},
}),
);
@ -287,11 +287,11 @@ impl BlobMethods<crate::DomTypeHolder> for Blob {
Ok(FetchedData::ArrayBuffer(a)) => {
promise.resolve_native(&a, CanGc::note())
},
Err(e) => promise.reject_error(e),
Err(e) => promise.reject_error(e, CanGc::note()),
_ => panic!("Unexpected result from run_array_buffer_data_algorithm"),
}
},
Err(e) => promise.reject_error(e),
Err(e) => promise.reject_error(e, CanGc::note()),
};
}),
);

View file

@ -131,7 +131,7 @@ where
.handle_response(response, &promise, can_gc),
// https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetooth-requestdevice
// Step 3 - 4.
Err(error) => promise.reject_error(error.convert()),
Err(error) => promise.reject_error(error.convert(), can_gc),
}
}
}
@ -170,6 +170,7 @@ impl Bluetooth {
filters: &Option<Vec<BluetoothLEScanFilterInit>>,
optional_services: &[BluetoothServiceUUID],
sender: IpcSender<BluetoothResponseResult>,
can_gc: CanGc,
) {
// TODO: Step 1: Triggered by user activation.
@ -179,7 +180,7 @@ impl Bluetooth {
if let Some(filters) = filters {
// Step 2.1.
if filters.is_empty() {
p.reject_error(Type(FILTER_EMPTY_ERROR.to_owned()));
p.reject_error(Type(FILTER_EMPTY_ERROR.to_owned()), can_gc);
return;
}
@ -192,7 +193,7 @@ impl Bluetooth {
// Step 2.4.2.
Ok(f) => uuid_filters.push(f),
Err(e) => {
p.reject_error(e);
p.reject_error(e, can_gc);
return;
},
}
@ -206,7 +207,7 @@ impl Bluetooth {
let uuid = match BluetoothUUID::service(opt_service.clone()) {
Ok(u) => u.to_string(),
Err(e) => {
p.reject_error(e);
p.reject_error(e, can_gc);
return;
},
};
@ -229,7 +230,7 @@ impl Bluetooth {
if let PermissionState::Denied =
descriptor_permission_state(PermissionName::Bluetooth, None)
{
return p.reject_error(Error::NotFound);
return p.reject_error(Error::NotFound, can_gc);
}
// Note: Step 3, 6 - 8 are implemented in
@ -307,13 +308,13 @@ where
let canonicalized = match uuid_canonicalizer(u) {
Ok(canonicalized_uuid) => canonicalized_uuid.to_string(),
Err(e) => {
p.reject_error(e);
p.reject_error(e, can_gc);
return p;
},
};
// Step 2.
if uuid_is_blocklisted(canonicalized.as_ref(), Blocklist::All) {
p.reject_error(Security);
p.reject_error(Security, can_gc);
return p;
}
Some(canonicalized)
@ -323,7 +324,7 @@ where
// Step 3 - 4.
if !connected {
p.reject_error(Network);
p.reject_error(Network, can_gc);
return p;
}
@ -550,13 +551,19 @@ impl BluetoothMethods<crate::DomTypeHolder> for Bluetooth {
if (option.filters.is_some() && option.acceptAllDevices) ||
(option.filters.is_none() && !option.acceptAllDevices)
{
p.reject_error(Error::Type(OPTIONS_ERROR.to_owned()));
p.reject_error(Error::Type(OPTIONS_ERROR.to_owned()), can_gc);
return p;
}
// Step 2.
let sender = response_async(&p, self);
self.request_bluetooth_devices(&p, &option.filters, &option.optionalServices, sender);
self.request_bluetooth_devices(
&p,
&option.filters,
&option.optionalServices,
sender,
can_gc,
);
//Note: Step 3 - 4. in response function, Step 5. in handle_response function.
p
}
@ -616,7 +623,7 @@ impl AsyncBluetoothListener for Bluetooth {
BluetoothResponse::GetAvailability(is_available) => {
promise.resolve_native(&is_available, can_gc);
},
_ => promise.reject_error(Error::Type("Something went wrong...".to_owned())),
_ => promise.reject_error(Error::Type("Something went wrong...".to_owned()), can_gc),
}
}
}
@ -689,7 +696,7 @@ impl PermissionAlgorithm for Bluetooth {
for filter in filters {
match canonicalize_filter(filter) {
Ok(f) => scan_filters.push(f),
Err(error) => return promise.reject_error(error),
Err(error) => return promise.reject_error(error, CanGc::note()),
}
}
@ -710,7 +717,7 @@ impl PermissionAlgorithm for Bluetooth {
match receiver.recv().unwrap() {
Ok(true) => (),
Ok(false) => continue,
Err(error) => return promise.reject_error(error.convert()),
Err(error) => return promise.reject_error(error.convert(), CanGc::note()),
};
}
@ -739,7 +746,7 @@ impl PermissionAlgorithm for Bluetooth {
) {
// Step 1.
if descriptor.filters.is_some() == descriptor.acceptAllDevices {
return promise.reject_error(Error::Type(OPTIONS_ERROR.to_owned()));
return promise.reject_error(Error::Type(OPTIONS_ERROR.to_owned()), CanGc::note());
}
// Step 2.
@ -750,6 +757,7 @@ impl PermissionAlgorithm for Bluetooth {
&descriptor.filters,
&descriptor.optionalServices,
sender,
CanGc::note(),
);
// NOTE: Step 3. is in BluetoothPermissionResult's `handle_response` function.

View file

@ -336,7 +336,7 @@ impl AsyncBluetoothListener for BluetoothDevice {
// Step 3.2.
promise.resolve_native(&(), can_gc);
},
_ => promise.reject_error(Error::Type("Something went wrong...".to_owned())),
_ => promise.reject_error(Error::Type("Something went wrong...".to_owned()), can_gc),
}
}
}

View file

@ -137,7 +137,7 @@ impl AsyncBluetoothListener for BluetoothPermissionResult {
// Step 8.
promise.resolve_native(self, can_gc);
},
_ => promise.reject_error(Error::Type("Something went wrong...".to_owned())),
_ => promise.reject_error(Error::Type("Something went wrong...".to_owned()), can_gc),
}
}
}

View file

@ -154,13 +154,13 @@ impl BluetoothRemoteGATTCharacteristicMethods<crate::DomTypeHolder>
// Step 1.
if uuid_is_blocklisted(self.uuid.as_ref(), Blocklist::Reads) {
p.reject_error(Security);
p.reject_error(Security, can_gc);
return p;
}
// Step 2.
if !self.Service().Device().get_gatt().Connected() {
p.reject_error(Network);
p.reject_error(Network, can_gc);
return p;
}
@ -168,7 +168,7 @@ impl BluetoothRemoteGATTCharacteristicMethods<crate::DomTypeHolder>
// Step 5.1.
if !self.Properties().Read() {
p.reject_error(NotSupported);
p.reject_error(NotSupported, can_gc);
return p;
}
@ -192,7 +192,7 @@ impl BluetoothRemoteGATTCharacteristicMethods<crate::DomTypeHolder>
// Step 1.
if uuid_is_blocklisted(self.uuid.as_ref(), Blocklist::Writes) {
p.reject_error(Security);
p.reject_error(Security, can_gc);
return p;
}
@ -203,13 +203,13 @@ impl BluetoothRemoteGATTCharacteristicMethods<crate::DomTypeHolder>
};
if vec.len() > MAXIMUM_ATTRIBUTE_LENGTH {
p.reject_error(InvalidModification);
p.reject_error(InvalidModification, can_gc);
return p;
}
// Step 4.
if !self.Service().Device().get_gatt().Connected() {
p.reject_error(Network);
p.reject_error(Network, can_gc);
return p;
}
@ -220,7 +220,7 @@ impl BluetoothRemoteGATTCharacteristicMethods<crate::DomTypeHolder>
self.Properties().WriteWithoutResponse() ||
self.Properties().AuthenticatedSignedWrites())
{
p.reject_error(NotSupported);
p.reject_error(NotSupported, can_gc);
return p;
}
@ -243,19 +243,19 @@ impl BluetoothRemoteGATTCharacteristicMethods<crate::DomTypeHolder>
// Step 1.
if uuid_is_blocklisted(self.uuid.as_ref(), Blocklist::Reads) {
p.reject_error(Security);
p.reject_error(Security, can_gc);
return p;
}
// Step 2.
if !self.Service().Device().get_gatt().Connected() {
p.reject_error(Network);
p.reject_error(Network, can_gc);
return p;
}
// Step 5.
if !(self.Properties().Notify() || self.Properties().Indicate()) {
p.reject_error(NotSupported);
p.reject_error(NotSupported, can_gc);
return p;
}
@ -359,7 +359,7 @@ impl AsyncBluetoothListener for BluetoothRemoteGATTCharacteristic {
// (StopNotification) Step 5.
promise.resolve_native(self, can_gc);
},
_ => promise.reject_error(Error::Type("Something went wrong...".to_owned())),
_ => promise.reject_error(Error::Type("Something went wrong...".to_owned()), can_gc),
}
}
}

View file

@ -102,7 +102,7 @@ impl BluetoothRemoteGATTDescriptorMethods<crate::DomTypeHolder> for BluetoothRem
// Step 1.
if uuid_is_blocklisted(self.uuid.as_ref(), Blocklist::Reads) {
p.reject_error(Security);
p.reject_error(Security, can_gc);
return p;
}
@ -114,7 +114,7 @@ impl BluetoothRemoteGATTDescriptorMethods<crate::DomTypeHolder> for BluetoothRem
.get_gatt()
.Connected()
{
p.reject_error(Network);
p.reject_error(Network, can_gc);
return p;
}
@ -139,7 +139,7 @@ impl BluetoothRemoteGATTDescriptorMethods<crate::DomTypeHolder> for BluetoothRem
// Step 1.
if uuid_is_blocklisted(self.uuid.as_ref(), Blocklist::Writes) {
p.reject_error(Security);
p.reject_error(Security, can_gc);
return p;
}
@ -149,7 +149,7 @@ impl BluetoothRemoteGATTDescriptorMethods<crate::DomTypeHolder> for BluetoothRem
ArrayBufferViewOrArrayBuffer::ArrayBuffer(ab) => ab.to_vec(),
};
if vec.len() > MAXIMUM_ATTRIBUTE_LENGTH {
p.reject_error(InvalidModification);
p.reject_error(InvalidModification, can_gc);
return p;
}
@ -161,7 +161,7 @@ impl BluetoothRemoteGATTDescriptorMethods<crate::DomTypeHolder> for BluetoothRem
.get_gatt()
.Connected()
{
p.reject_error(Network);
p.reject_error(Network, can_gc);
return p;
}
@ -207,7 +207,7 @@ impl AsyncBluetoothListener for BluetoothRemoteGATTDescriptor {
// TODO: Resolve promise with undefined instead of a value.
promise.resolve_native(&(), can_gc);
},
_ => promise.reject_error(Error::Type("Something went wrong...".to_owned())),
_ => promise.reject_error(Error::Type("Something went wrong...".to_owned()), can_gc),
}
}
}

View file

@ -155,9 +155,9 @@ impl AsyncBluetoothListener for BluetoothRemoteGATTServer {
// Step 5.2.3
if self.Device().is_represented_device_null() {
if let Err(e) = self.Device().garbage_collect_the_connection() {
return promise.reject_error(e);
return promise.reject_error(e, can_gc);
}
return promise.reject_error(Error::Network);
return promise.reject_error(Error::Network, can_gc);
}
// Step 5.2.4.
@ -184,7 +184,7 @@ impl AsyncBluetoothListener for BluetoothRemoteGATTServer {
}
promise.resolve_native(&services, can_gc);
},
_ => promise.reject_error(Error::Type("Something went wrong...".to_owned())),
_ => promise.reject_error(Error::Type("Something went wrong...".to_owned()), can_gc),
}
}
}

View file

@ -203,7 +203,7 @@ impl AsyncBluetoothListener for BluetoothRemoteGATTService {
}
promise.resolve_native(&services, can_gc);
},
_ => promise.reject_error(Error::Type("Something went wrong...".to_owned())),
_ => promise.reject_error(Error::Type("Something went wrong...".to_owned()), can_gc),
}
}
}

View file

@ -4291,7 +4291,7 @@ impl Document {
let promise = Promise::new_in_current_realm(InRealm::Already(&in_realm_proof), can_gc);
// Step 2
if self.fullscreen_element.get().is_none() {
promise.reject_error(Error::Type(String::from("fullscreen is null")));
promise.reject_error(Error::Type(String::from("fullscreen is null")), can_gc);
return promise;
}
// TODO Step 3-6

View file

@ -4610,7 +4610,10 @@ impl TaskOnce for ElementPerformFullscreenEnter {
document
.upcast::<EventTarget>()
.fire_event(atom!("fullscreenerror"), CanGc::note());
promise.reject_error(Error::Type(String::from("fullscreen is not connected")));
promise.reject_error(
Error::Type(String::from("fullscreen is not connected")),
CanGc::note(),
);
return;
}

View file

@ -191,7 +191,7 @@ impl FontFace {
let font_status_promise = Promise::new(global, can_gc);
// If any of them fail to parse correctly, reject font faces [[FontStatusPromise]] with a
// DOMException named "SyntaxError"
font_status_promise.reject_error(Error::Syntax);
font_status_promise.reject_error(Error::Syntax, can_gc);
// set font faces corresponding attributes to the empty string, and set font faces status
// attribute to "error"
@ -505,7 +505,7 @@ impl FontFaceMethods<crate::DomTypeHolder> for FontFace {
// [[FontStatusPromise]] with a DOMException whose name is "NetworkError"
// and set font faces status attribute to "error".
font_face.status.set(FontFaceLoadStatus::Error);
font_face.font_status_promise.reject_error(Error::Network);
font_face.font_status_promise.reject_error(Error::Network, CanGc::note());
}
Some(template) => {
// Step 5.2. Otherwise, font face now represents the loaded font;

View file

@ -145,38 +145,56 @@ impl GamepadHapticActuatorMethods<crate::DomTypeHolder> for GamepadHapticActuato
// <https://www.w3.org/TR/gamepad/#dfn-valid-dual-rumble-effect>
GamepadHapticEffectType::Dual_rumble => {
if *params.strongMagnitude < 0.0 || *params.strongMagnitude > 1.0 {
playing_effect_promise.reject_error(Error::Type(
"Strong magnitude value is not within range of 0.0 to 1.0.".to_string(),
));
playing_effect_promise.reject_error(
Error::Type(
"Strong magnitude value is not within range of 0.0 to 1.0.".to_string(),
),
can_gc,
);
return playing_effect_promise;
} else if *params.weakMagnitude < 0.0 || *params.weakMagnitude > 1.0 {
playing_effect_promise.reject_error(Error::Type(
"Weak magnitude value is not within range of 0.0 to 1.0.".to_string(),
));
playing_effect_promise.reject_error(
Error::Type(
"Weak magnitude value is not within range of 0.0 to 1.0.".to_string(),
),
can_gc,
);
return playing_effect_promise;
}
},
// <https://www.w3.org/TR/gamepad/#dfn-valid-trigger-rumble-effect>
GamepadHapticEffectType::Trigger_rumble => {
if *params.strongMagnitude < 0.0 || *params.strongMagnitude > 1.0 {
playing_effect_promise.reject_error(Error::Type(
"Strong magnitude value is not within range of 0.0 to 1.0.".to_string(),
));
playing_effect_promise.reject_error(
Error::Type(
"Strong magnitude value is not within range of 0.0 to 1.0.".to_string(),
),
can_gc,
);
return playing_effect_promise;
} else if *params.weakMagnitude < 0.0 || *params.weakMagnitude > 1.0 {
playing_effect_promise.reject_error(Error::Type(
"Weak magnitude value is not within range of 0.0 to 1.0.".to_string(),
));
playing_effect_promise.reject_error(
Error::Type(
"Weak magnitude value is not within range of 0.0 to 1.0.".to_string(),
),
can_gc,
);
return playing_effect_promise;
} else if *params.leftTrigger < 0.0 || *params.leftTrigger > 1.0 {
playing_effect_promise.reject_error(Error::Type(
"Left trigger value is not within range of 0.0 to 1.0.".to_string(),
));
playing_effect_promise.reject_error(
Error::Type(
"Left trigger value is not within range of 0.0 to 1.0.".to_string(),
),
can_gc,
);
return playing_effect_promise;
} else if *params.rightTrigger < 0.0 || *params.rightTrigger > 1.0 {
playing_effect_promise.reject_error(Error::Type(
"Right trigger value is not within range of 0.0 to 1.0.".to_string(),
));
playing_effect_promise.reject_error(
Error::Type(
"Right trigger value is not within range of 0.0 to 1.0.".to_string(),
),
can_gc,
);
return playing_effect_promise;
}
},
@ -184,7 +202,7 @@ impl GamepadHapticActuatorMethods<crate::DomTypeHolder> for GamepadHapticActuato
let document = self.global().as_window().Document();
if !document.is_fully_active() {
playing_effect_promise.reject_error(Error::InvalidState);
playing_effect_promise.reject_error(Error::InvalidState, can_gc);
}
self.sequence_id.set(self.sequence_id.get().wrapping_add(1));
@ -201,7 +219,7 @@ impl GamepadHapticActuatorMethods<crate::DomTypeHolder> for GamepadHapticActuato
}
if !self.effects.contains(&type_) {
playing_effect_promise.reject_error(Error::NotSupported);
playing_effect_promise.reject_error(Error::NotSupported, can_gc);
return playing_effect_promise;
}
@ -251,7 +269,7 @@ impl GamepadHapticActuatorMethods<crate::DomTypeHolder> for GamepadHapticActuato
let document = self.global().as_window().Document();
if !document.is_fully_active() {
promise.reject_error(Error::InvalidState);
promise.reject_error(Error::InvalidState, can_gc);
return promise;
}

View file

@ -2702,12 +2702,12 @@ impl GlobalScope {
let in_realm_proof = AlreadyInRealm::assert();
let p = Promise::new_in_current_realm(InRealm::Already(&in_realm_proof), can_gc);
if options.resizeWidth.is_some_and(|w| w == 0) {
p.reject_error(Error::InvalidState);
p.reject_error(Error::InvalidState, can_gc);
return p;
}
if options.resizeHeight.is_some_and(|w| w == 0) {
p.reject_error(Error::InvalidState);
p.reject_error(Error::InvalidState, can_gc);
return p;
}
@ -2715,7 +2715,7 @@ impl GlobalScope {
ImageBitmapSource::HTMLCanvasElement(ref canvas) => {
// https://html.spec.whatwg.org/multipage/#check-the-usability-of-the-image-argument
if !canvas.is_valid() {
p.reject_error(Error::InvalidState);
p.reject_error(Error::InvalidState, can_gc);
return p;
}
@ -2736,7 +2736,7 @@ impl GlobalScope {
ImageBitmapSource::OffscreenCanvas(ref canvas) => {
// https://html.spec.whatwg.org/multipage/#check-the-usability-of-the-image-argument
if !canvas.is_valid() {
p.reject_error(Error::InvalidState);
p.reject_error(Error::InvalidState, can_gc);
return p;
}
@ -2754,7 +2754,7 @@ impl GlobalScope {
p
},
_ => {
p.reject_error(Error::NotSupported);
p.reject_error(Error::NotSupported, can_gc);
p
},
}

View file

@ -1220,7 +1220,7 @@ impl HTMLMediaElement {
for promise in &*promises {
match result {
Ok(ref value) => promise.resolve_native(value, CanGc::note()),
Err(ref error) => promise.reject_error(error.clone()),
Err(ref error) => promise.reject_error(error.clone(), CanGc::note()),
}
}
}
@ -2195,7 +2195,7 @@ impl HTMLMediaElementMethods<crate::DomTypeHolder> for HTMLMediaElement {
.get()
.is_some_and(|e| e.Code() == MEDIA_ERR_SRC_NOT_SUPPORTED)
{
promise.reject_error(Error::NotSupported);
promise.reject_error(Error::NotSupported, can_gc);
return promise;
}

View file

@ -146,7 +146,7 @@ impl OfflineAudioContextMethods<crate::DomTypeHolder> for OfflineAudioContext {
fn StartRendering(&self, comp: InRealm, can_gc: CanGc) -> Rc<Promise> {
let promise = Promise::new_in_current_realm(comp, can_gc);
if self.rendering_started.get() {
promise.reject_error(Error::InvalidState);
promise.reject_error(Error::InvalidState, can_gc);
return promise;
}
self.rendering_started.set(true);
@ -221,7 +221,10 @@ impl OfflineAudioContextMethods<crate::DomTypeHolder> for OfflineAudioContext {
.resume()
.is_err()
{
promise.reject_error(Error::Type("Could not start offline rendering".to_owned()));
promise.reject_error(
Error::Type("Could not start offline rendering".to_owned()),
can_gc,
);
}
promise

View file

@ -104,7 +104,7 @@ impl Permissions {
let root_desc = match Permissions::create_descriptor(cx, permissionDesc) {
Ok(descriptor) => descriptor,
Err(error) => {
p.reject_error(error);
p.reject_error(error, can_gc);
return p;
},
};
@ -119,7 +119,7 @@ impl Permissions {
let bluetooth_desc = match Bluetooth::create_descriptor(cx, permissionDesc) {
Ok(descriptor) => descriptor,
Err(error) => {
p.reject_error(error);
p.reject_error(error, can_gc);
return p;
},
};

View file

@ -221,12 +221,12 @@ impl Promise {
self.reject(cx, v.handle(), can_gc);
}
pub(crate) fn reject_error(&self, error: Error) {
pub(crate) fn reject_error(&self, error: Error, can_gc: CanGc) {
let cx = GlobalScope::get_cx();
let _ac = enter_realm(self);
rooted!(in(*cx) let mut v = UndefinedValue());
error.to_jsval(cx, &self.global(), v.handle_mut());
self.reject(cx, v.handle(), CanGc::note());
self.reject(cx, v.handle(), can_gc);
}
#[allow(unsafe_code)]

View file

@ -961,7 +961,7 @@ impl ReadableStreamMethods<crate::DomTypeHolder> for ReadableStream {
// If ! IsReadableStreamLocked(this) is true,
// return a promise rejected with a TypeError exception.
let promise = Promise::new(&self.global(), can_gc);
promise.reject_error(Error::Type("stream is not locked".to_owned()));
promise.reject_error(Error::Type("stream is not locked".to_owned()), can_gc);
promise
} else {
// Return ! ReadableStreamCancel(this, reason).

View file

@ -161,7 +161,7 @@ impl ReadableStreamBYOBReader {
/// <https://streams.spec.whatwg.org/#abstract-opdef-readablestreambyobreaderrelease>
pub(crate) fn release(&self, can_gc: CanGc) -> Fallible<()> {
// Perform ! ReadableStreamReaderGenericRelease(reader).
self.generic_release()?;
self.generic_release(can_gc)?;
// Let e be a new TypeError exception.
let cx = GlobalScope::get_cx();
rooted!(in(*cx) let mut error = UndefinedValue());
@ -277,26 +277,29 @@ impl ReadableStreamBYOBReaderMethods<crate::DomTypeHolder> for ReadableStreamBYO
let cx = GlobalScope::get_cx();
// If view.[[ByteLength]] is 0, return a promise rejected with a TypeError exception.
if view.byte_length() == 0 {
promise.reject_error(Error::Type("view byte length is 0".to_owned()));
promise.reject_error(Error::Type("view byte length is 0".to_owned()), can_gc);
return promise;
}
// If view.[[ViewedArrayBuffer]].[[ArrayBufferByteLength]] is 0,
// return a promise rejected with a TypeError exception.
if view.viewed_buffer_array_byte_length(cx) == 0 {
promise.reject_error(Error::Type("viewed buffer byte length is 0".to_owned()));
promise.reject_error(
Error::Type("viewed buffer byte length is 0".to_owned()),
can_gc,
);
return promise;
}
// If ! IsDetachedBuffer(view.[[ViewedArrayBuffer]]) is true,
// return a promise rejected with a TypeError exception.
if view.is_detached_buffer(cx) {
promise.reject_error(Error::Type("view is detached".to_owned()));
promise.reject_error(Error::Type("view is detached".to_owned()), can_gc);
return promise;
}
// If options["min"] is 0, return a promise rejected with a TypeError exception.
if options.min == 0 {
promise.reject_error(Error::Type("min is 0".to_owned()));
promise.reject_error(Error::Type("min is 0".to_owned()), can_gc);
return promise;
}
@ -304,21 +307,30 @@ impl ReadableStreamBYOBReaderMethods<crate::DomTypeHolder> for ReadableStreamBYO
if view.has_typed_array_name() {
// If options["min"] > view.[[ArrayLength]], return a promise rejected with a RangeError exception.
if options.min > (view.array_length() as u64) {
promise.reject_error(Error::Type("min is greater than array length".to_owned()));
promise.reject_error(
Error::Type("min is greater than array length".to_owned()),
can_gc,
);
return promise;
}
} else {
// Otherwise (i.e., it is a DataView),
// If options["min"] > view.[[ByteLength]], return a promise rejected with a RangeError exception.
if options.min > (view.byte_length() as u64) {
promise.reject_error(Error::Type("min is greater than byte length".to_owned()));
promise.reject_error(
Error::Type("min is greater than byte length".to_owned()),
can_gc,
);
return promise;
}
}
// If this.[[stream]] is undefined, return a promise rejected with a TypeError exception.
if self.stream.get().is_none() {
promise.reject_error(Error::Type("min is greater than byte length".to_owned()));
promise.reject_error(
Error::Type("min is greater than byte length".to_owned()),
can_gc,
);
return promise;
}

View file

@ -253,7 +253,7 @@ impl ReadableStreamDefaultReader {
/// <https://streams.spec.whatwg.org/#abstract-opdef-readablestreamdefaultreaderrelease>
pub(crate) fn release(&self, can_gc: CanGc) -> Fallible<()> {
// Perform ! ReadableStreamReaderGenericRelease(reader).
self.generic_release()?;
self.generic_release(can_gc)?;
// Let e be a new TypeError exception.
let cx = GlobalScope::get_cx();
rooted!(in(*cx) let mut error = UndefinedValue());

View file

@ -76,7 +76,7 @@ pub(crate) trait ReadableStreamGenericReader {
/// <https://streams.spec.whatwg.org/#readable-stream-reader-generic-release>
#[allow(unsafe_code)]
fn generic_release(&self) -> Fallible<()> {
fn generic_release(&self, can_gc: CanGc) -> Fallible<()> {
// Let stream be reader.[[stream]].
// Assert: stream is not undefined.
@ -88,8 +88,10 @@ pub(crate) trait ReadableStreamGenericReader {
if stream.is_readable() {
// If stream.[[state]] is "readable", reject reader.[[closedPromise]] with a TypeError exception.
self.get_closed_promise()
.reject_error(Error::Type("stream state is not readable".to_owned()));
self.get_closed_promise().reject_error(
Error::Type("stream state is not readable".to_owned()),
can_gc,
);
} else {
// Otherwise, set reader.[[closedPromise]] to a promise rejected with a TypeError exception.
let cx = GlobalScope::get_cx();
@ -104,7 +106,7 @@ pub(crate) trait ReadableStreamGenericReader {
&stream.global(),
cx,
error.handle(),
CanGc::note(),
can_gc,
));
}
// Set reader.[[closedPromise]].[[PromiseIsHandled]] to true.
@ -132,7 +134,7 @@ pub(crate) trait ReadableStreamGenericReader {
// If this.[[stream]] is undefined,
// return a promise rejected with a TypeError exception.
let promise = Promise::new(global, can_gc);
promise.reject_error(Error::Type("stream is undefined".to_owned()));
promise.reject_error(Error::Type("stream is undefined".to_owned()), can_gc);
promise
} else {
// Return ! ReadableStreamReaderGenericCancel(this, reason).

View file

@ -556,17 +556,19 @@ impl RTCPeerConnectionMethods<crate::DomTypeHolder> for RTCPeerConnection {
) -> Rc<Promise> {
let p = Promise::new_in_current_realm(comp, can_gc);
if candidate.sdpMid.is_none() && candidate.sdpMLineIndex.is_none() {
p.reject_error(Error::Type(
"one of sdpMid and sdpMLineIndex must be set".to_string(),
));
p.reject_error(
Error::Type("one of sdpMid and sdpMLineIndex must be set".to_string()),
can_gc,
);
return p;
}
// XXXManishearth add support for sdpMid
if candidate.sdpMLineIndex.is_none() {
p.reject_error(Error::Type(
"servo only supports sdpMLineIndex right now".to_string(),
));
p.reject_error(
Error::Type("servo only supports sdpMLineIndex right now".to_string()),
can_gc,
);
return p;
}
@ -591,7 +593,7 @@ impl RTCPeerConnectionMethods<crate::DomTypeHolder> for RTCPeerConnection {
fn CreateOffer(&self, _options: &RTCOfferOptions, comp: InRealm, can_gc: CanGc) -> Rc<Promise> {
let p = Promise::new_in_current_realm(comp, can_gc);
if self.closed.get() {
p.reject_error(Error::InvalidState);
p.reject_error(Error::InvalidState, can_gc);
return p;
}
self.offer_promises.borrow_mut().push(p.clone());
@ -608,7 +610,7 @@ impl RTCPeerConnectionMethods<crate::DomTypeHolder> for RTCPeerConnection {
) -> Rc<Promise> {
let p = Promise::new_in_current_realm(comp, can_gc);
if self.closed.get() {
p.reject_error(Error::InvalidState);
p.reject_error(Error::InvalidState, can_gc);
return p;
}
self.answer_promises.borrow_mut().push(p.clone());

View file

@ -80,7 +80,7 @@ impl ServiceWorkerContainerMethods<crate::DomTypeHolder> for ServiceWorkerContai
Ok(url) => url,
Err(_) => {
// B: Step 1
promise.reject_error(Error::Type("Invalid script URL".to_owned()));
promise.reject_error(Error::Type("Invalid script URL".to_owned()), can_gc);
return promise;
},
};
@ -92,7 +92,7 @@ impl ServiceWorkerContainerMethods<crate::DomTypeHolder> for ServiceWorkerContai
match api_base_url.join(inner_scope) {
Ok(url) => url,
Err(_) => {
promise.reject_error(Error::Type("Invalid scope URL".to_owned()));
promise.reject_error(Error::Type("Invalid scope URL".to_owned()), can_gc);
return promise;
},
}
@ -106,7 +106,10 @@ impl ServiceWorkerContainerMethods<crate::DomTypeHolder> for ServiceWorkerContai
match script_url.scheme() {
"https" | "http" => {},
_ => {
promise.reject_error(Error::Type("Only secure origins are allowed".to_owned()));
promise.reject_error(
Error::Type("Only secure origins are allowed".to_owned()),
can_gc,
);
return promise;
},
}
@ -114,9 +117,10 @@ impl ServiceWorkerContainerMethods<crate::DomTypeHolder> for ServiceWorkerContai
if script_url.path().to_ascii_lowercase().contains("%2f") ||
script_url.path().to_ascii_lowercase().contains("%5c")
{
promise.reject_error(Error::Type(
"Script URL contains forbidden characters".to_owned(),
));
promise.reject_error(
Error::Type("Script URL contains forbidden characters".to_owned()),
can_gc,
);
return promise;
}
@ -124,7 +128,10 @@ impl ServiceWorkerContainerMethods<crate::DomTypeHolder> for ServiceWorkerContai
match scope.scheme() {
"https" | "http" => {},
_ => {
promise.reject_error(Error::Type("Only secure origins are allowed".to_owned()));
promise.reject_error(
Error::Type("Only secure origins are allowed".to_owned()),
can_gc,
);
return promise;
},
}
@ -132,9 +139,10 @@ impl ServiceWorkerContainerMethods<crate::DomTypeHolder> for ServiceWorkerContai
if scope.path().to_ascii_lowercase().contains("%2f") ||
scope.path().to_ascii_lowercase().contains("%5c")
{
promise.reject_error(Error::Type(
"Scope URL contains forbidden characters".to_owned(),
));
promise.reject_error(
Error::Type("Scope URL contains forbidden characters".to_owned()),
can_gc,
);
return promise;
}
@ -198,21 +206,23 @@ impl RegisterJobResultHandler {
.expect("No promise to resolve for SW Register job.");
// Step 1
self.task_source.queue(
task!(reject_promise_with_security_error: move || {
self.task_source
.queue(task!(reject_promise_with_security_error: move || {
let promise = promise.root();
let _ac = enter_realm(&*promise.global());
match error {
JobError::TypeError => {
promise.reject_error(Error::Type("Failed to register a ServiceWorker".to_string()));
promise.reject_error(
Error::Type("Failed to register a ServiceWorker".to_string()),
CanGc::note(),
);
},
JobError::SecurityError => {
promise.reject_error(Error::Security);
promise.reject_error(Error::Security, CanGc::note());
},
}
})
);
}));
// TODO: step 2, handle equivalent jobs.
},

View file

@ -148,7 +148,7 @@ impl SubtleCryptoMethods<crate::DomTypeHolder> for SubtleCrypto {
{
Ok(algorithm) => algorithm,
Err(e) => {
promise.reject_error(e);
promise.reject_error(e, can_gc);
return promise;
},
};
@ -171,7 +171,7 @@ impl SubtleCryptoMethods<crate::DomTypeHolder> for SubtleCrypto {
let key = trusted_key.root();
if !valid_usage || normalized_algorithm.name() != key_alg {
promise.reject_error(Error::InvalidAccess);
promise.reject_error(Error::InvalidAccess, CanGc::note());
return;
}
@ -186,7 +186,7 @@ impl SubtleCryptoMethods<crate::DomTypeHolder> for SubtleCrypto {
array_buffer_ptr.handle_mut(),
CanGc::note(),
) {
promise.reject_error(e);
promise.reject_error(e, CanGc::note());
return;
}
promise.resolve_native(&*array_buffer_ptr.handle(), CanGc::note());
@ -209,7 +209,7 @@ impl SubtleCryptoMethods<crate::DomTypeHolder> for SubtleCrypto {
{
Ok(algorithm) => algorithm,
Err(e) => {
promise.reject_error(e);
promise.reject_error(e, can_gc);
return promise;
},
};
@ -234,7 +234,7 @@ impl SubtleCryptoMethods<crate::DomTypeHolder> for SubtleCrypto {
rooted!(in(*cx) let mut array_buffer_ptr = ptr::null_mut::<JSObject>());
if !valid_usage || normalized_algorithm.name() != key_alg {
promise.reject_error(Error::InvalidAccess);
promise.reject_error(Error::InvalidAccess, CanGc::note());
return;
}
@ -246,7 +246,7 @@ impl SubtleCryptoMethods<crate::DomTypeHolder> for SubtleCrypto {
array_buffer_ptr.handle_mut(),
CanGc::note(),
) {
promise.reject_error(e);
promise.reject_error(e, CanGc::note());
return;
}
@ -281,7 +281,7 @@ impl SubtleCryptoMethods<crate::DomTypeHolder> for SubtleCrypto {
Ok(algorithm) => algorithm,
Err(e) => {
// Step 4. If an error occurred, return a Promise rejected with normalizedAlgorithm.
promise.reject_error(e);
promise.reject_error(e, can_gc);
return promise;
},
};
@ -305,14 +305,14 @@ impl SubtleCryptoMethods<crate::DomTypeHolder> for SubtleCrypto {
// Step 8. If the name member of normalizedAlgorithm is not equal to the name attribute of the
// [[algorithm]] internal slot of key then throw an InvalidAccessError.
if normalized_algorithm.name() != key.algorithm() {
promise.reject_error(Error::InvalidAccess);
promise.reject_error(Error::InvalidAccess, CanGc::note());
return;
}
// Step 9. If the [[usages]] internal slot of key does not contain an entry that is "sign",
// then throw an InvalidAccessError.
if !key.usages().contains(&KeyUsage::Sign) {
promise.reject_error(Error::InvalidAccess);
promise.reject_error(Error::InvalidAccess, CanGc::note());
return;
}
@ -322,7 +322,7 @@ impl SubtleCryptoMethods<crate::DomTypeHolder> for SubtleCrypto {
let result = match normalized_algorithm.sign(cx, &key, &data) {
Ok(signature) => signature,
Err(e) => {
promise.reject_error(e);
promise.reject_error(e, CanGc::note());
return;
}
};
@ -373,7 +373,7 @@ impl SubtleCryptoMethods<crate::DomTypeHolder> for SubtleCrypto {
Ok(algorithm) => algorithm,
Err(e) => {
// Step 5. If an error occurred, return a Promise rejected with normalizedAlgorithm.
promise.reject_error(e);
promise.reject_error(e, can_gc);
return promise;
},
};
@ -397,14 +397,14 @@ impl SubtleCryptoMethods<crate::DomTypeHolder> for SubtleCrypto {
// Step 9. If the name member of normalizedAlgorithm is not equal to the name attribute of the
// [[algorithm]] internal slot of key then throw an InvalidAccessError.
if normalized_algorithm.name() != key.algorithm() {
promise.reject_error(Error::InvalidAccess);
promise.reject_error(Error::InvalidAccess, CanGc::note());
return;
}
// Step 10. If the [[usages]] internal slot of key does not contain an entry that is "verify",
// then throw an InvalidAccessError.
if !key.usages().contains(&KeyUsage::Verify) {
promise.reject_error(Error::InvalidAccess);
promise.reject_error(Error::InvalidAccess, CanGc::note());
return;
}
@ -414,7 +414,7 @@ impl SubtleCryptoMethods<crate::DomTypeHolder> for SubtleCrypto {
let result = match normalized_algorithm.verify(cx, &key, &data, &signature) {
Ok(result) => result,
Err(e) => {
promise.reject_error(e);
promise.reject_error(e, CanGc::note());
return;
}
};
@ -451,7 +451,7 @@ impl SubtleCryptoMethods<crate::DomTypeHolder> for SubtleCrypto {
Ok(normalized_algorithm) => normalized_algorithm,
Err(e) => {
// Step 4. If an error occurred, return a Promise rejected with normalizedAlgorithm.
promise.reject_error(e);
promise.reject_error(e, can_gc);
return promise;
},
};
@ -473,7 +473,7 @@ impl SubtleCryptoMethods<crate::DomTypeHolder> for SubtleCrypto {
let digest = match normalized_algorithm.digest(&data) {
Ok(digest) => digest,
Err(e) => {
promise.reject_error(e);
promise.reject_error(e, CanGc::note());
return;
}
};
@ -506,7 +506,7 @@ impl SubtleCryptoMethods<crate::DomTypeHolder> for SubtleCrypto {
let normalized_algorithm = match normalize_algorithm_for_generate_key(cx, &algorithm) {
Ok(algorithm) => algorithm,
Err(e) => {
promise.reject_error(e);
promise.reject_error(e, can_gc);
return promise;
},
};
@ -523,7 +523,7 @@ impl SubtleCryptoMethods<crate::DomTypeHolder> for SubtleCrypto {
match key {
Ok(key) => promise.resolve_native(&key, CanGc::note()),
Err(e) => promise.reject_error(e),
Err(e) => promise.reject_error(e, CanGc::note()),
}
}));
@ -552,7 +552,7 @@ impl SubtleCryptoMethods<crate::DomTypeHolder> for SubtleCrypto {
Ok(algorithm) => algorithm,
Err(e) => {
// Step 3. If an error occurred, return a Promise rejected with normalizedAlgorithm.
promise.reject_error(e);
promise.reject_error(e, can_gc);
return promise;
},
};
@ -564,7 +564,7 @@ impl SubtleCryptoMethods<crate::DomTypeHolder> for SubtleCrypto {
Ok(algorithm) => algorithm,
Err(e) => {
// Step 5. If an error occurred, return a Promise rejected with normalizedDerivedKeyAlgorithmImport.
promise.reject_error(e);
promise.reject_error(e, can_gc);
return promise;
},
};
@ -576,7 +576,7 @@ impl SubtleCryptoMethods<crate::DomTypeHolder> for SubtleCrypto {
Ok(algorithm) => algorithm,
Err(e) => {
// Step 7. If an error occurred, return a Promise rejected with normalizedDerivedKeyAlgorithmLength.
promise.reject_error(e);
promise.reject_error(e, can_gc);
return promise;
},
};
@ -602,7 +602,7 @@ impl SubtleCryptoMethods<crate::DomTypeHolder> for SubtleCrypto {
// Step 12. If the [[usages]] internal slot of baseKey does not contain an entry that is
// "deriveKey", then throw an InvalidAccessError.
if !base_key.usages().contains(&KeyUsage::DeriveKey) {
promise.reject_error(Error::InvalidAccess);
promise.reject_error(Error::InvalidAccess, CanGc::note());
return;
}
@ -611,7 +611,7 @@ impl SubtleCryptoMethods<crate::DomTypeHolder> for SubtleCrypto {
let length = match normalized_derived_key_algorithm_length.get_key_length() {
Ok(length) => length,
Err(e) => {
promise.reject_error(e);
promise.reject_error(e, CanGc::note());
return;
}
};
@ -621,7 +621,7 @@ impl SubtleCryptoMethods<crate::DomTypeHolder> for SubtleCrypto {
let secret = match normalized_algorithm.derive_bits(&base_key, Some(length)){
Ok(secret) => secret,
Err(e) => {
promise.reject_error(e);
promise.reject_error(e, CanGc::note());
return;
}
};
@ -640,7 +640,7 @@ impl SubtleCryptoMethods<crate::DomTypeHolder> for SubtleCrypto {
let result = match result {
Ok(key) => key,
Err(e) => {
promise.reject_error(e);
promise.reject_error(e, CanGc::note());
return;
}
};
@ -648,7 +648,7 @@ impl SubtleCryptoMethods<crate::DomTypeHolder> for SubtleCrypto {
// Step 17. If the [[type]] internal slot of result is "secret" or "private" and usages
// is empty, then throw a SyntaxError.
if matches!(result.Type(), KeyType::Secret | KeyType::Private) && result.usages().is_empty() {
promise.reject_error(Error::Syntax);
promise.reject_error(Error::Syntax, CanGc::note());
return;
}
@ -680,7 +680,7 @@ impl SubtleCryptoMethods<crate::DomTypeHolder> for SubtleCrypto {
Ok(algorithm) => algorithm,
Err(e) => {
// Step 3. If an error occurred, return a Promise rejected with normalizedAlgorithm.
promise.reject_error(e);
promise.reject_error(e, can_gc);
return promise;
},
};
@ -707,7 +707,7 @@ impl SubtleCryptoMethods<crate::DomTypeHolder> for SubtleCrypto {
// Step 8. If the [[usages]] internal slot of baseKey does not contain an entry that
// is "deriveBits", then throw an InvalidAccessError.
if !base_key.usages().contains(&KeyUsage::DeriveBits) {
promise.reject_error(Error::InvalidAccess);
promise.reject_error(Error::InvalidAccess, CanGc::note());
return;
}
@ -718,7 +718,7 @@ impl SubtleCryptoMethods<crate::DomTypeHolder> for SubtleCrypto {
let result = match normalized_algorithm.derive_bits(&base_key, length) {
Ok(derived_bits) => derived_bits,
Err(e) => {
promise.reject_error(e);
promise.reject_error(e, CanGc::note());
return;
}
};
@ -749,7 +749,7 @@ impl SubtleCryptoMethods<crate::DomTypeHolder> for SubtleCrypto {
let normalized_algorithm = match normalize_algorithm_for_import_key(cx, &algorithm) {
Ok(algorithm) => algorithm,
Err(e) => {
promise.reject_error(e);
promise.reject_error(e, can_gc);
return promise;
},
};
@ -760,7 +760,7 @@ impl SubtleCryptoMethods<crate::DomTypeHolder> for SubtleCrypto {
let data_string = match json_web_key.k {
Some(s) => s.to_string(),
None => {
promise.reject_error(Error::Syntax);
promise.reject_error(Error::Syntax, can_gc);
return promise;
},
};
@ -770,7 +770,7 @@ impl SubtleCryptoMethods<crate::DomTypeHolder> for SubtleCrypto {
{
Ok(data) => data,
Err(_) => {
promise.reject_error(Error::Syntax);
promise.reject_error(Error::Syntax, can_gc);
return promise;
},
}
@ -792,7 +792,7 @@ impl SubtleCryptoMethods<crate::DomTypeHolder> for SubtleCrypto {
format, &data, extractable, key_usages, CanGc::note());
match imported_key {
Ok(k) => promise.resolve_native(&k, CanGc::note()),
Err(e) => promise.reject_error(e),
Err(e) => promise.reject_error(e, CanGc::note()),
};
}));
@ -821,11 +821,11 @@ impl SubtleCryptoMethods<crate::DomTypeHolder> for SubtleCrypto {
if matches!(
alg_name.as_str(), ALG_SHA1 | ALG_SHA256 | ALG_SHA384 | ALG_SHA512 | ALG_HKDF | ALG_PBKDF2
) {
promise.reject_error(Error::NotSupported);
promise.reject_error(Error::NotSupported, CanGc::note());
return;
}
if !key.Extractable() {
promise.reject_error(Error::InvalidAccess);
promise.reject_error(Error::InvalidAccess, CanGc::note());
return;
}
let exported_key = match alg_name.as_str() {
@ -848,7 +848,7 @@ impl SubtleCryptoMethods<crate::DomTypeHolder> for SubtleCrypto {
},
}
},
Err(e) => promise.reject_error(e),
Err(e) => promise.reject_error(e, CanGc::note()),
}
}),
);
@ -871,7 +871,7 @@ impl SubtleCryptoMethods<crate::DomTypeHolder> for SubtleCrypto {
let normalized_algorithm = match normalize_algorithm_for_key_wrap(cx, &wrap_algorithm) {
Ok(algorithm) => algorithm,
Err(e) => {
promise.reject_error(e);
promise.reject_error(e, can_gc);
return promise;
},
};
@ -892,21 +892,21 @@ impl SubtleCryptoMethods<crate::DomTypeHolder> for SubtleCrypto {
let names_match = normalized_algorithm.name() == wrapping_alg_name.as_str();
if !valid_wrap_usage || !names_match || !key.Extractable() {
promise.reject_error(Error::InvalidAccess);
promise.reject_error(Error::InvalidAccess, CanGc::note());
return;
}
if matches!(
alg_name.as_str(), ALG_SHA1 | ALG_SHA256 | ALG_SHA384 | ALG_SHA512 | ALG_HKDF | ALG_PBKDF2
) {
promise.reject_error(Error::NotSupported);
promise.reject_error(Error::NotSupported, CanGc::note());
return;
}
let exported_key = match subtle.export_key_aes(format, &key) {
Ok(k) => k,
Err(e) => {
promise.reject_error(e);
promise.reject_error(e, CanGc::note());
return;
},
};
@ -919,19 +919,19 @@ impl SubtleCryptoMethods<crate::DomTypeHolder> for SubtleCrypto {
// TODO: Support more than just a subset of the JWK dict, or find a way to
// stringify via SM internals
let Some(k) = key.k else {
promise.reject_error(Error::Syntax);
promise.reject_error(Error::Syntax, CanGc::note());
return;
};
let Some(alg) = key.alg else {
promise.reject_error(Error::Syntax);
promise.reject_error(Error::Syntax, CanGc::note());
return;
};
let Some(ext) = key.ext else {
promise.reject_error(Error::Syntax);
promise.reject_error(Error::Syntax, CanGc::note());
return;
};
let Some(key_ops) = key.key_ops else {
promise.reject_error(Error::Syntax);
promise.reject_error(Error::Syntax, CanGc::note());
return;
};
let key_ops_str = key_ops.iter().map(|op| op.to_string()).collect::<Vec<String>>();
@ -971,7 +971,7 @@ impl SubtleCryptoMethods<crate::DomTypeHolder> for SubtleCrypto {
match result {
Ok(_) => promise.resolve_native(&*array_buffer_ptr, CanGc::note()),
Err(e) => promise.reject_error(e),
Err(e) => promise.reject_error(e, CanGc::note()),
}
}),
);
@ -1001,7 +1001,7 @@ impl SubtleCryptoMethods<crate::DomTypeHolder> for SubtleCrypto {
let normalized_algorithm = match normalize_algorithm_for_key_wrap(cx, &unwrap_algorithm) {
Ok(algorithm) => algorithm,
Err(e) => {
promise.reject_error(e);
promise.reject_error(e, can_gc);
return promise;
},
};
@ -1009,7 +1009,7 @@ impl SubtleCryptoMethods<crate::DomTypeHolder> for SubtleCrypto {
match normalize_algorithm_for_import_key(cx, &unwrapped_key_algorithm) {
Ok(algorithm) => algorithm,
Err(e) => {
promise.reject_error(e);
promise.reject_error(e, can_gc);
return promise;
},
};
@ -1026,7 +1026,7 @@ impl SubtleCryptoMethods<crate::DomTypeHolder> for SubtleCrypto {
let valid_usage = unwrapping_key.usages().contains(&KeyUsage::UnwrapKey);
if !valid_usage || normalized_algorithm.name() != alg_name.as_str() {
promise.reject_error(Error::InvalidAccess);
promise.reject_error(Error::InvalidAccess, CanGc::note());
return;
}
@ -1061,7 +1061,7 @@ impl SubtleCryptoMethods<crate::DomTypeHolder> for SubtleCrypto {
let bytes = match result {
Ok(bytes) => bytes,
Err(e) => {
promise.reject_error(e);
promise.reject_error(e, CanGc::note());
return;
},
};
@ -1072,7 +1072,7 @@ impl SubtleCryptoMethods<crate::DomTypeHolder> for SubtleCrypto {
match parse_jwk(&bytes, normalized_key_algorithm.clone(), extractable, &key_usages) {
Ok(bytes) => bytes,
Err(e) => {
promise.reject_error(e);
promise.reject_error(e, CanGc::note());
return;
}
}
@ -1081,7 +1081,7 @@ impl SubtleCryptoMethods<crate::DomTypeHolder> for SubtleCrypto {
match normalized_key_algorithm.import_key(&subtle, format, &import_key_bytes,
extractable, key_usages, CanGc::note()) {
Ok(imported_key) => promise.resolve_native(&imported_key, CanGc::note()),
Err(e) => promise.reject_error(e),
Err(e) => promise.reject_error(e, CanGc::note()),
}
}),
);

View file

@ -988,8 +988,8 @@ impl TestBindingMethods<crate::DomTypeHolder> for TestBinding {
p.reject(cx, v, can_gc);
}
fn PromiseRejectWithTypeError(&self, p: &Promise, s: USVString) {
p.reject_error(Error::Type(s.0));
fn PromiseRejectWithTypeError(&self, p: &Promise, s: USVString, can_gc: CanGc) {
p.reject_error(Error::Type(s.0), can_gc);
}
#[cfg_attr(crown, allow(crown::unrooted_must_root))]

View file

@ -132,7 +132,7 @@ impl GPUMethods<crate::DomTypeHolder> for GPU {
))
.is_err()
{
promise.reject_error(Error::Operation);
promise.reject_error(Error::Operation, can_gc);
}
promise
}

View file

@ -122,10 +122,10 @@ impl GPUAdapterMethods<crate::DomTypeHolder> for GPUAdapter {
if let Some(feature) = gpu_to_wgt_feature(ext) {
required_features.insert(feature);
} else {
promise.reject_error(Error::Type(format!(
"{} is not supported feature",
ext.as_str()
)));
promise.reject_error(
Error::Type(format!("{} is not supported feature", ext.as_str())),
can_gc,
);
return promise;
}
}
@ -135,7 +135,7 @@ impl GPUAdapterMethods<crate::DomTypeHolder> for GPUAdapter {
for (limit, value) in (*limits).iter() {
if !set_limit(&mut required_limits, limit.as_ref(), *value) {
warn!("Unknown GPUDevice limit: {limit}");
promise.reject_error(Error::Operation);
promise.reject_error(Error::Operation, can_gc);
return promise;
}
}
@ -163,7 +163,7 @@ impl GPUAdapterMethods<crate::DomTypeHolder> for GPUAdapter {
})
.is_err()
{
promise.reject_error(Error::Operation);
promise.reject_error(Error::Operation, can_gc);
}
// Step 5
promise
@ -225,12 +225,13 @@ impl AsyncWGPUListener for GPUAdapter {
promise.resolve_native(&device, can_gc);
},
WebGPUResponse::Device((_, _, Err(RequestDeviceError::UnsupportedFeature(f)))) => {
promise.reject_error(Error::Type(
RequestDeviceError::UnsupportedFeature(f).to_string(),
))
promise.reject_error(
Error::Type(RequestDeviceError::UnsupportedFeature(f).to_string()),
can_gc,
)
},
WebGPUResponse::Device((_, _, Err(RequestDeviceError::LimitsExceeded(_)))) => {
promise.reject_error(Error::Operation)
promise.reject_error(Error::Operation, can_gc)
},
WebGPUResponse::Device((device_id, queue_id, Err(e))) => {
let device = GPUDevice::new(

View file

@ -193,7 +193,7 @@ impl GPUBufferMethods<crate::DomTypeHolder> for GPUBuffer {
fn Unmap(&self) {
// Step 1
if let Some(promise) = self.pending_map.borrow_mut().take() {
promise.reject_error(Error::Abort);
promise.reject_error(Error::Abort, CanGc::note());
}
// Step 2
let mut mapping = self.mapping.borrow_mut().take();
@ -251,7 +251,7 @@ impl GPUBufferMethods<crate::DomTypeHolder> for GPUBuffer {
let promise = Promise::new_in_current_realm(comp, can_gc);
// Step 2
if self.pending_map.borrow().is_some() {
promise.reject_error(Error::Operation);
promise.reject_error(Error::Operation, can_gc);
return promise;
}
// Step 4
@ -265,7 +265,7 @@ impl GPUBufferMethods<crate::DomTypeHolder> for GPUBuffer {
.dispatch_error(webgpu::Error::Validation(String::from(
"Invalid MapModeFlags",
)));
self.map_failure(&promise);
self.map_failure(&promise, can_gc);
return promise;
},
};
@ -283,7 +283,7 @@ impl GPUBufferMethods<crate::DomTypeHolder> for GPUBuffer {
"Failed to send BufferMapAsync ({:?}) ({})",
self.buffer.0, e
);
self.map_failure(&promise);
self.map_failure(&promise, can_gc);
return promise;
}
// Step 6
@ -361,7 +361,7 @@ impl GPUBufferMethods<crate::DomTypeHolder> for GPUBuffer {
}
impl GPUBuffer {
fn map_failure(&self, p: &Rc<Promise>) {
fn map_failure(&self, p: &Rc<Promise>, can_gc: CanGc) {
let mut pending_map = self.pending_map.borrow_mut();
// Step 1
if pending_map.as_ref() != Some(p) {
@ -374,9 +374,9 @@ impl GPUBuffer {
pending_map.take();
// Step 4
if self.device.is_lost() {
p.reject_error(Error::Abort);
p.reject_error(Error::Abort, can_gc);
} else {
p.reject_error(Error::Operation);
p.reject_error(Error::Operation, can_gc);
}
}
@ -404,7 +404,7 @@ impl GPUBuffer {
match mapping {
Err(error) => {
*pending_map = None;
p.reject_error(error.clone());
p.reject_error(error.clone(), can_gc);
},
Ok(mut mapping) => {
// Step 5
@ -426,7 +426,7 @@ impl AsyncWGPUListener for GPUBuffer {
WebGPUResponse::BufferMapAsync(Ok(mapping)) => {
self.map_success(promise, mapping, can_gc)
},
WebGPUResponse::BufferMapAsync(Err(_)) => self.map_failure(promise),
WebGPUResponse::BufferMapAsync(Err(_)) => self.map_failure(promise, can_gc),
_ => unreachable!("Wrong response received on AsyncWGPUListener for GPUBuffer"),
}
}

View file

@ -588,7 +588,7 @@ impl AsyncWGPUListener for GPUDevice {
Ok(None) | Err(PopError::Lost) => {
promise.resolve_native(&None::<Option<GPUError>>, can_gc)
},
Err(PopError::Empty) => promise.reject_error(Error::Operation),
Err(PopError::Empty) => promise.reject_error(Error::Operation, can_gc),
Ok(Some(error)) => {
let error = GPUError::from_error(&self.global(), error, can_gc);
promise.resolve_native(&error, can_gc);

View file

@ -228,7 +228,7 @@ impl AsyncWGPUListener for GPUQueue {
},
_ => {
warn!("GPUQueue received wrong WebGPUResponse");
promise.reject_error(Error::Operation);
promise.reject_error(Error::Operation, can_gc);
},
}
}

View file

@ -836,14 +836,14 @@ impl XRSessionMethods<crate::DomTypeHolder> for XRSession {
if !self.is_immersive() &&
(ty == XRReferenceSpaceType::Bounded_floor || ty == XRReferenceSpaceType::Unbounded)
{
p.reject_error(Error::NotSupported);
p.reject_error(Error::NotSupported, can_gc);
return p;
}
match ty {
XRReferenceSpaceType::Unbounded => {
// XXXmsub2 figure out how to support this
p.reject_error(Error::NotSupported)
p.reject_error(Error::NotSupported, can_gc)
},
ty => {
if ty != XRReferenceSpaceType::Viewer &&
@ -857,7 +857,7 @@ impl XRSessionMethods<crate::DomTypeHolder> for XRSession {
.iter()
.any(|f| *f == s)
{
p.reject_error(Error::NotSupported);
p.reject_error(Error::NotSupported, can_gc);
return p;
}
}
@ -927,7 +927,7 @@ impl XRSessionMethods<crate::DomTypeHolder> for XRSession {
.iter()
.any(|f| f == "hit-test")
{
p.reject_error(Error::NotSupported);
p.reject_error(Error::NotSupported, can_gc);
return p;
}
@ -1035,12 +1035,15 @@ impl XRSessionMethods<crate::DomTypeHolder> for XRSession {
supported_frame_rates.is_empty() ||
self.ended.get()
{
promise.reject_error(Error::InvalidState);
promise.reject_error(Error::InvalidState, can_gc);
return promise;
}
if !supported_frame_rates.contains(&*rate) {
promise.reject_error(Error::Type("Provided framerate not supported".into()));
promise.reject_error(
Error::Type("Provided framerate not supported".into()),
can_gc,
);
return promise;
}
}

View file

@ -171,13 +171,13 @@ impl XRSystemMethods<crate::DomTypeHolder> for XRSystem {
if pref!(dom_webxr_unsafe_assume_user_intent) {
warn!("The dom.webxr.unsafe-assume-user-intent preference assumes user intent to enter WebXR.");
} else {
promise.reject_error(Error::Security);
promise.reject_error(Error::Security, can_gc);
return promise;
}
}
if self.pending_or_active_session() {
promise.reject_error(Error::InvalidState);
promise.reject_error(Error::InvalidState, can_gc);
return promise;
}
@ -200,7 +200,7 @@ impl XRSystemMethods<crate::DomTypeHolder> for XRSystem {
if mode != XRSessionMode::Inline {
self.pending_immersive_session.set(false);
}
promise.reject_error(Error::NotSupported);
promise.reject_error(Error::NotSupported, can_gc);
return promise;
}
}
@ -291,7 +291,7 @@ impl XRSystem {
if mode != XRSessionMode::Inline {
self.pending_immersive_session.set(false);
}
promise.reject_error(Error::NotSupported);
promise.reject_error(Error::NotSupported, can_gc);
return;
},
};

View file

@ -77,7 +77,7 @@ impl XRTestMethods<crate::DomTypeHolder> for XRTest {
match get_origin(o) {
Ok(origin) => Some(origin),
Err(e) => {
p.reject_error(e);
p.reject_error(e, can_gc);
return p;
},
}
@ -89,7 +89,7 @@ impl XRTestMethods<crate::DomTypeHolder> for XRTest {
match get_origin(o) {
Ok(origin) => Some(origin),
Err(e) => {
p.reject_error(e);
p.reject_error(e, can_gc);
return p;
},
}
@ -100,7 +100,7 @@ impl XRTestMethods<crate::DomTypeHolder> for XRTest {
let views = match get_views(&init.views) {
Ok(views) => views,
Err(e) => {
p.reject_error(e);
p.reject_error(e, can_gc);
return p;
},
};
@ -115,7 +115,7 @@ impl XRTestMethods<crate::DomTypeHolder> for XRTest {
let w = match get_world(w) {
Ok(w) => w,
Err(e) => {
p.reject_error(e);
p.reject_error(e, can_gc);
return p;
},
};

View file

@ -141,7 +141,7 @@ impl WorkletMethods<crate::DomTypeHolder> for Worklet {
Err(err) => {
// Step 4.
debug!("URL {:?} parse error {:?}.", module_url.0, err);
promise.reject_error(Error::Syntax);
promise.reject_error(Error::Syntax, can_gc);
return promise;
},
};

View file

@ -718,7 +718,10 @@ impl WritableStream {
if self.is_closed() || self.is_errored() {
// return a promise rejected with a TypeError exception.
let promise = Promise::new(global, can_gc);
promise.reject_error(Error::Type("Stream is closed or errored.".to_string()));
promise.reject_error(
Error::Type("Stream is closed or errored.".to_string()),
can_gc,
);
return promise;
}
@ -913,7 +916,7 @@ impl WritableStreamMethods<crate::DomTypeHolder> for WritableStream {
if self.is_locked() {
// return a promise rejected with a TypeError exception.
let promise = Promise::new(&global, can_gc);
promise.reject_error(Error::Type("Stream is locked.".to_string()));
promise.reject_error(Error::Type("Stream is locked.".to_string()), can_gc);
return promise;
}
@ -930,7 +933,7 @@ impl WritableStreamMethods<crate::DomTypeHolder> for WritableStream {
if self.is_locked() {
// return a promise rejected with a TypeError exception.
let promise = Promise::new(&global, can_gc);
promise.reject_error(Error::Type("Stream is locked.".to_string()));
promise.reject_error(Error::Type("Stream is locked.".to_string()), can_gc);
return promise;
}
@ -938,9 +941,10 @@ impl WritableStreamMethods<crate::DomTypeHolder> for WritableStream {
if self.close_queued_or_in_flight() {
// return a promise rejected with a TypeError exception.
let promise = Promise::new(&global, can_gc);
promise.reject_error(Error::Type(
"Stream has closed queued or in-flight".to_string(),
));
promise.reject_error(
Error::Type("Stream has closed queued or in-flight".to_string()),
can_gc,
);
return promise;
}

View file

@ -451,7 +451,7 @@ impl WritableStreamDefaultController {
};
result.unwrap_or_else(|e| {
let promise = Promise::new(global, can_gc);
promise.reject_error(e);
promise.reject_error(e, can_gc);
promise
})
}
@ -477,7 +477,7 @@ impl WritableStreamDefaultController {
};
result.unwrap_or_else(|e| {
let promise = Promise::new(global, can_gc);
promise.reject_error(e);
promise.reject_error(e, can_gc);
promise
})
}
@ -498,7 +498,7 @@ impl WritableStreamDefaultController {
};
result.unwrap_or_else(|e| {
let promise = Promise::new(global, can_gc);
promise.reject_error(e);
promise.reject_error(e, can_gc);
promise
})
}

View file

@ -293,9 +293,10 @@ impl WritableStreamDefaultWriter {
.is_some_and(|current_stream| current_stream == stream)
{
let promise = Promise::new(global, can_gc);
promise.reject_error(Error::Type(
"Stream is not equal to writer stream".to_string(),
));
promise.reject_error(
Error::Type("Stream is not equal to writer stream".to_string()),
can_gc,
);
return promise;
}
@ -316,9 +317,10 @@ impl WritableStreamDefaultWriter {
// return a promise rejected with a TypeError exception
// indicating that the stream is closing or closed
let promise = Promise::new(global, can_gc);
promise.reject_error(Error::Type(
"Stream has been closed, or has close queued or in-flight".to_string(),
));
promise.reject_error(
Error::Type("Stream has been closed, or has close queued or in-flight".to_string()),
can_gc,
);
return promise;
}
@ -415,7 +417,7 @@ impl WritableStreamDefaultWriterMethods<crate::DomTypeHolder> for WritableStream
if self.stream.get().is_none() {
// return a promise rejected with a TypeError exception.
let promise = Promise::new(&global, can_gc);
promise.reject_error(Error::Type("Stream is undefined".to_string()));
promise.reject_error(Error::Type("Stream is undefined".to_string()), can_gc);
return promise;
}
@ -433,16 +435,17 @@ impl WritableStreamDefaultWriterMethods<crate::DomTypeHolder> for WritableStream
let Some(stream) = self.stream.get() else {
// If stream is undefined,
// return a promise rejected with a TypeError exception.
promise.reject_error(Error::Type("Stream is undefined".to_string()));
promise.reject_error(Error::Type("Stream is undefined".to_string()), can_gc);
return promise;
};
// If ! WritableStreamCloseQueuedOrInFlight(stream) is true
if stream.close_queued_or_in_flight() {
// return a promise rejected with a TypeError exception.
promise.reject_error(Error::Type(
"Stream has closed queued or in-flight".to_string(),
));
promise.reject_error(
Error::Type("Stream has closed queued or in-flight".to_string()),
can_gc,
);
return promise;
}
@ -482,7 +485,7 @@ impl WritableStreamDefaultWriterMethods<crate::DomTypeHolder> for WritableStream
// return a promise rejected with a TypeError exception.
let global = GlobalScope::from_safe_context(cx, realm);
let promise = Promise::new(&global, can_gc);
promise.reject_error(Error::Type("Stream is undefined".to_string()));
promise.reject_error(Error::Type("Stream is undefined".to_string()), can_gc);
return promise;
}

View file

@ -151,7 +151,7 @@ pub(crate) fn Fetch(
let request = match Request::Constructor(global, None, can_gc, input, init) {
Err(e) => {
response.error_stream(e.clone(), can_gc);
promise.reject_error(e);
promise.reject_error(e, can_gc);
return promise;
},
Ok(r) => {
@ -223,7 +223,10 @@ impl FetchResponseListener for FetchContext {
match fetch_metadata {
// Step 4.1
Err(_) => {
promise.reject_error(Error::Type("Network error occurred".to_string()));
promise.reject_error(
Error::Type("Network error occurred".to_string()),
CanGc::note(),
);
self.fetch_promise = Some(TrustedPromise::new(promise));
let response = self.response_object.root();
response.set_type(DOMResponseType::Error, CanGc::note());

View file

@ -485,7 +485,7 @@ DOMInterfaces = {
#FIXME(jdm): This should be 'register': False, but then we don't generate enum types
'TestBinding': {
'inRealms': ['PromiseAttribute', 'PromiseNativeHandler'],
'canGc': ['InterfaceAttribute', 'GetInterfaceAttributeNullable', 'ReceiveInterface', 'ReceiveInterfaceSequence', 'ReceiveNullableInterface', 'PromiseAttribute', 'PromiseNativeHandler', 'PromiseResolveNative', 'PromiseRejectNative'],
'canGc': ['InterfaceAttribute', 'GetInterfaceAttributeNullable', 'ReceiveInterface', 'ReceiveInterfaceSequence', 'ReceiveNullableInterface', 'PromiseAttribute', 'PromiseNativeHandler', 'PromiseResolveNative', 'PromiseRejectNative', 'PromiseRejectWithTypeError'],
},
'TestWorklet': {