script: Add message to NotFoundError (#39394)

Adding an optional message to be attached to a NotFoundError.

Testing: Just a refactor
Part of #39053

---------

Signed-off-by: Rodion Borovyk <rodion.borovyk@gmail.com>
This commit is contained in:
Rodion Borovyk 2025-09-25 14:16:50 +02:00 committed by GitHub
parent ffdb7d3663
commit 9713bb9e1b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
18 changed files with 37 additions and 38 deletions

View file

@ -99,9 +99,18 @@ pub(crate) fn create_dom_exception(
result: Error, result: Error,
can_gc: CanGc, can_gc: CanGc,
) -> Result<DomRoot<DOMException>, JsEngineError> { ) -> Result<DomRoot<DOMException>, JsEngineError> {
let new_custom_exception = |error_name, message| {
Ok(DOMException::new_with_custom_message(
global, error_name, message, can_gc,
))
};
let code = match result { let code = match result {
Error::IndexSize => DOMErrorName::IndexSizeError, Error::IndexSize => DOMErrorName::IndexSizeError,
Error::NotFound => DOMErrorName::NotFoundError, Error::NotFound(Some(custom_message)) => {
return new_custom_exception(DOMErrorName::NotFoundError, custom_message);
},
Error::NotFound(None) => DOMErrorName::NotFoundError,
Error::HierarchyRequest => DOMErrorName::HierarchyRequestError, Error::HierarchyRequest => DOMErrorName::HierarchyRequestError,
Error::WrongDocument => DOMErrorName::WrongDocumentError, Error::WrongDocument => DOMErrorName::WrongDocumentError,
Error::InvalidCharacter => DOMErrorName::InvalidCharacterError, Error::InvalidCharacter => DOMErrorName::InvalidCharacterError,
@ -109,12 +118,7 @@ pub(crate) fn create_dom_exception(
Error::InUseAttribute => DOMErrorName::InUseAttributeError, Error::InUseAttribute => DOMErrorName::InUseAttributeError,
Error::InvalidState => DOMErrorName::InvalidStateError, Error::InvalidState => DOMErrorName::InvalidStateError,
Error::Syntax(Some(custom_message)) => { Error::Syntax(Some(custom_message)) => {
return Ok(DOMException::new_with_custom_message( return new_custom_exception(DOMErrorName::SyntaxError, custom_message);
global,
DOMErrorName::SyntaxError,
custom_message,
can_gc,
));
}, },
Error::Syntax(None) => DOMErrorName::SyntaxError, Error::Syntax(None) => DOMErrorName::SyntaxError,
Error::Namespace => DOMErrorName::NamespaceError, Error::Namespace => DOMErrorName::NamespaceError,
@ -125,12 +129,7 @@ pub(crate) fn create_dom_exception(
Error::Timeout => DOMErrorName::TimeoutError, Error::Timeout => DOMErrorName::TimeoutError,
Error::InvalidNodeType => DOMErrorName::InvalidNodeTypeError, Error::InvalidNodeType => DOMErrorName::InvalidNodeTypeError,
Error::DataClone(Some(custom_message)) => { Error::DataClone(Some(custom_message)) => {
return Ok(DOMException::new_with_custom_message( return new_custom_exception(DOMErrorName::DataCloneError, custom_message);
global,
DOMErrorName::DataCloneError,
custom_message,
can_gc,
));
}, },
Error::DataClone(None) => DOMErrorName::DataCloneError, Error::DataClone(None) => DOMErrorName::DataCloneError,
Error::Data => DOMErrorName::DataError, Error::Data => DOMErrorName::DataError,

View file

@ -230,7 +230,7 @@ impl Bluetooth {
if let PermissionState::Denied = if let PermissionState::Denied =
descriptor_permission_state(PermissionName::Bluetooth, None) descriptor_permission_state(PermissionName::Bluetooth, None)
{ {
return p.reject_error(Error::NotFound, can_gc); return p.reject_error(Error::NotFound(None), can_gc);
} }
// Note: Step 3, 6 - 8 are implemented in // Note: Step 3, 6 - 8 are implemented in
@ -530,7 +530,7 @@ impl Convert<Error> for BluetoothError {
match self { match self {
BluetoothError::Type(message) => Error::Type(message), BluetoothError::Type(message) => Error::Type(message),
BluetoothError::Network => Error::Network, BluetoothError::Network => Error::Network,
BluetoothError::NotFound => Error::NotFound, BluetoothError::NotFound => Error::NotFound(None),
BluetoothError::NotSupported => Error::NotSupported, BluetoothError::NotSupported => Error::NotSupported,
BluetoothError::Security => Error::Security, BluetoothError::Security => Error::Security,
BluetoothError::InvalidState => Error::InvalidState, BluetoothError::InvalidState => Error::InvalidState,

View file

@ -69,7 +69,7 @@ impl Callback for RepresentationDataPromiseRejectionHandler {
fn callback(&self, _cx: SafeJSContext, _v: SafeHandleValue, _realm: InRealm, can_gc: CanGc) { fn callback(&self, _cx: SafeJSContext, _v: SafeHandleValue, _realm: InRealm, can_gc: CanGc) {
// Reject p with "NotFoundError" DOMException in realm. // Reject p with "NotFoundError" DOMException in realm.
// Return p. // Return p.
self.promise.reject_error(Error::NotFound, can_gc); self.promise.reject_error(Error::NotFound(None), can_gc);
} }
} }

View file

@ -84,7 +84,7 @@ impl Callback for RepresentationDataPromiseRejectionHandler {
/// Substeps of 8.1.2.2 If representationDataPromise was rejected, then: /// Substeps of 8.1.2.2 If representationDataPromise was rejected, then:
fn callback(&self, _cx: SafeJSContext, _v: SafeHandleValue, _realm: InRealm, can_gc: CanGc) { fn callback(&self, _cx: SafeJSContext, _v: SafeHandleValue, _realm: InRealm, can_gc: CanGc) {
// 1. Reject p with "NotFoundError" DOMException in realm. // 1. Reject p with "NotFoundError" DOMException in realm.
self.promise.reject_error(Error::NotFound, can_gc); self.promise.reject_error(Error::NotFound(None), can_gc);
} }
} }
@ -299,7 +299,7 @@ impl ClipboardItemMethods<crate::DomTypeHolder> for ClipboardItem {
} }
// Step 9 Reject p with "NotFoundError" DOMException in realm. // Step 9 Reject p with "NotFoundError" DOMException in realm.
p.reject_error(Error::NotFound, can_gc); p.reject_error(Error::NotFound(None), can_gc);
// Step 10 Return p. // Step 10 Return p.
Ok(p) Ok(p)

View file

@ -3181,7 +3181,7 @@ impl ElementMethods<crate::DomTypeHolder> for Element {
// https://dom.spec.whatwg.org/#dom-element-removeattributenode // https://dom.spec.whatwg.org/#dom-element-removeattributenode
fn RemoveAttributeNode(&self, attr: &Attr, can_gc: CanGc) -> Fallible<DomRoot<Attr>> { fn RemoveAttributeNode(&self, attr: &Attr, can_gc: CanGc) -> Fallible<DomRoot<Attr>> {
self.remove_first_matching_attribute(|a| a == attr, can_gc) self.remove_first_matching_attribute(|a| a == attr, can_gc)
.ok_or(Error::NotFound) .ok_or(Error::NotFound(None))
} }
// https://dom.spec.whatwg.org/#dom-element-hasattribute // https://dom.spec.whatwg.org/#dom-element-hasattribute

View file

@ -294,7 +294,7 @@ impl ElementInternalsMethods<crate::DomTypeHolder> for ElementInternals {
.upcast::<Node>() .upcast::<Node>()
.is_shadow_including_inclusive_ancestor_of(anchor.upcast::<Node>()) .is_shadow_including_inclusive_ancestor_of(anchor.upcast::<Node>())
{ {
return Err(Error::NotFound); return Err(Error::NotFound(None));
} }
anchor anchor
}, },

View file

@ -107,7 +107,7 @@ impl FormDataMethods<crate::DomTypeHolder> for FormData {
// Step 1.1.2. If submitters form owner is not form, then throw a "NotFoundError" // Step 1.1.2. If submitters form owner is not form, then throw a "NotFoundError"
// DOMException. // DOMException.
if !matches!(submit_button.form_owner(), Some(owner) if *owner == *form) { if !matches!(submit_button.form_owner(), Some(owner) if *owner == *form) {
return Err(Error::NotFound); return Err(Error::NotFound(None));
} }
Ok(submit_button) Ok(submit_button)

View file

@ -337,12 +337,12 @@ impl HTMLFormElementMethods<crate::DomTypeHolder> for HTMLFormElement {
let owner = match submitters_owner { let owner = match submitters_owner {
Some(owner) => owner, Some(owner) => owner,
None => { None => {
return Err(Error::NotFound); return Err(Error::NotFound(None));
}, },
}; };
if *owner != *self { if *owner != *self {
return Err(Error::NotFound); return Err(Error::NotFound(None));
} }
submit_button submit_button

View file

@ -201,7 +201,7 @@ impl HTMLOptionsCollectionMethods<crate::DomTypeHolder> for HTMLOptionsCollectio
// Step 2 // Step 2
let before_node = before_element.upcast::<Node>(); let before_node = before_element.upcast::<Node>();
if !root.is_ancestor_of(before_node) { if !root.is_ancestor_of(before_node) {
return Err(Error::NotFound); return Err(Error::NotFound(None));
} }
// Step 3 // Step 3

View file

@ -275,7 +275,7 @@ impl ScriptOrigin {
fetch_options, fetch_options,
type_, type_,
unminified_dir, unminified_dir,
import_map: Err(Error::NotFound), import_map: Err(Error::NotFound(None)),
} }
} }
@ -911,7 +911,7 @@ impl HTMLScriptElement {
options, options,
script_type, script_type,
self.global().unminified_js_dir(), self.global().unminified_js_dir(),
Err(Error::NotFound), Err(Error::NotFound(None)),
)); ));
if was_parser_inserted && if was_parser_inserted &&

View file

@ -309,7 +309,7 @@ impl IDBDatabaseMethods<crate::DomTypeHolder> for IDBDatabase {
.iter() .iter()
.any(|store_name| store_name.to_string() == name.to_string()) .any(|store_name| store_name.to_string() == name.to_string())
{ {
return Err(Error::NotFound); return Err(Error::NotFound(None));
} }
// Step 5 // Step 5

View file

@ -268,7 +268,7 @@ impl IDBTransactionMethods<crate::DomTypeHolder> for IDBTransaction {
// Step 2: Check that the object store exists // Step 2: Check that the object store exists
if !self.object_store_names.Contains(name.clone()) { if !self.object_store_names.Contains(name.clone()) {
return Err(Error::NotFound); return Err(Error::NotFound(None));
} }
// Step 3: Each call to this method on the same // Step 3: Each call to this method on the same

View file

@ -80,7 +80,7 @@ impl NamedNodeMapMethods<crate::DomTypeHolder> for NamedNodeMap {
let name = self.owner.parsed_name(name); let name = self.owner.parsed_name(name);
self.owner self.owner
.remove_attribute_by_name(&name, CanGc::note()) .remove_attribute_by_name(&name, CanGc::note())
.ok_or(Error::NotFound) .ok_or(Error::NotFound(None))
} }
// https://dom.spec.whatwg.org/#dom-namednodemap-removenameditemns // https://dom.spec.whatwg.org/#dom-namednodemap-removenameditemns
@ -92,7 +92,7 @@ impl NamedNodeMapMethods<crate::DomTypeHolder> for NamedNodeMap {
let ns = namespace_from_domstring(namespace); let ns = namespace_from_domstring(namespace);
self.owner self.owner
.remove_attribute(&ns, &LocalName::from(local_name), CanGc::note()) .remove_attribute(&ns, &LocalName::from(local_name), CanGc::note())
.ok_or(Error::NotFound) .ok_or(Error::NotFound(None))
} }
// https://dom.spec.whatwg.org/#dom-namednodemap-item // https://dom.spec.whatwg.org/#dom-namednodemap-item

View file

@ -2339,7 +2339,7 @@ impl Node {
// Step 3. // Step 3.
if let Some(child) = child { if let Some(child) = child {
if !parent.is_parent_of(child) { if !parent.is_parent_of(child) {
return Err(Error::NotFound); return Err(Error::NotFound(None));
} }
} }
@ -2719,8 +2719,8 @@ impl Node {
fn pre_remove(child: &Node, parent: &Node, can_gc: CanGc) -> Fallible<DomRoot<Node>> { fn pre_remove(child: &Node, parent: &Node, can_gc: CanGc) -> Fallible<DomRoot<Node>> {
// Step 1. // Step 1.
match child.GetParentNode() { match child.GetParentNode() {
Some(ref node) if &**node != parent => return Err(Error::NotFound), Some(ref node) if &**node != parent => return Err(Error::NotFound(None)),
None => return Err(Error::NotFound), None => return Err(Error::NotFound(None)),
_ => (), _ => (),
} }
@ -3485,7 +3485,7 @@ impl NodeMethods<crate::DomTypeHolder> for Node {
// Step 3. If childs parent is not parent, then throw a "NotFoundError" DOMException. // Step 3. If childs parent is not parent, then throw a "NotFoundError" DOMException.
if !self.is_parent_of(child) { if !self.is_parent_of(child) {
return Err(Error::NotFound); return Err(Error::NotFound(None));
} }
// Step 4. If node is not a DocumentFragment, DocumentType, Element, or CharacterData node, // Step 4. If node is not a DocumentFragment, DocumentType, Element, or CharacterData node,

View file

@ -220,7 +220,7 @@ impl SelectionMethods<crate::DomTypeHolder> for Selection {
return Ok(()); return Ok(());
} }
} }
Err(Error::NotFound) Err(Error::NotFound(None))
} }
// https://w3c.github.io/selection-api/#dom-selection-removeallranges // https://w3c.github.io/selection-api/#dom-selection-removeallranges

View file

@ -165,7 +165,7 @@ impl TextTrackMethods<crate::DomTypeHolder> for TextTrack {
let cues = self.get_cues(); let cues = self.get_cues();
let index = match cues.find(cue) { let index = match cues.find(cue) {
Some(i) => Ok(i), Some(i) => Ok(i),
None => Err(Error::NotFound), None => Err(Error::NotFound(None)),
}?; }?;
// Step 2 // Step 2
cues.remove(index); cues.remove(index);

View file

@ -1079,7 +1079,7 @@ impl ModuleOwner {
fetch_options, fetch_options,
ScriptType::Module, ScriptType::Module,
global.unminified_js_dir(), global.unminified_js_dir(),
Err(Error::NotFound), Err(Error::NotFound(None)),
)), )),
}, },
} }

View file

@ -16,7 +16,7 @@ pub enum Error {
/// IndexSizeError DOMException /// IndexSizeError DOMException
IndexSize, IndexSize,
/// NotFoundError DOMException /// NotFoundError DOMException
NotFound, NotFound(Option<String>),
/// HierarchyRequestError DOMException /// HierarchyRequestError DOMException
HierarchyRequest, HierarchyRequest,
/// WrongDocumentError DOMException /// WrongDocumentError DOMException