script: Add message to SyntaxError (#39056)

Adding an optional message to be attached to a SyntaxError. Unblocks
#39050.

The enum definition of Syntax is now `Syntax(Option<String>)`. Future
PRs should probably add more appropriate messages to some of the
`Syntax(None)`s.

Testing: Just a refactor
Fixes: Partially #39053

Signed-off-by: Ashwin Naren <arihant2math@gmail.com>
This commit is contained in:
Ashwin Naren 2025-09-01 22:51:36 -07:00 committed by GitHub
parent d01bba4e50
commit 97c8c83cbb
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
30 changed files with 82 additions and 70 deletions

View file

@ -1309,7 +1309,7 @@ impl CanvasState {
can_gc, can_gc,
))) )))
} else { } else {
Err(Error::Syntax) Err(Error::Syntax(None))
} }
} }

View file

@ -108,7 +108,15 @@ pub(crate) fn create_dom_exception(
Error::NotSupported => DOMErrorName::NotSupportedError, Error::NotSupported => DOMErrorName::NotSupportedError,
Error::InUseAttribute => DOMErrorName::InUseAttributeError, Error::InUseAttribute => DOMErrorName::InUseAttributeError,
Error::InvalidState => DOMErrorName::InvalidStateError, Error::InvalidState => DOMErrorName::InvalidStateError,
Error::Syntax => DOMErrorName::SyntaxError, Error::Syntax(Some(custom_message)) => {
return Ok(DOMException::new_with_custom_message(
global,
DOMErrorName::SyntaxError,
custom_message,
can_gc,
));
},
Error::Syntax(None) => DOMErrorName::SyntaxError,
Error::Namespace => DOMErrorName::NamespaceError, Error::Namespace => DOMErrorName::NamespaceError,
Error::InvalidAccess => DOMErrorName::InvalidAccessError, Error::InvalidAccess => DOMErrorName::InvalidAccessError,
Error::Security => DOMErrorName::SecurityError, Error::Security => DOMErrorName::SecurityError,

View file

@ -64,7 +64,7 @@ impl CanvasGradientMethods<crate::DomTypeHolder> for CanvasGradient {
let color = match parse_color(None, &color) { let color = match parse_color(None, &color) {
Ok(color) => color, Ok(color) => color,
Err(_) => return Err(Error::Syntax), Err(_) => return Err(Error::Syntax(None)),
}; };
self.stops.borrow_mut().push(CanvasGradientStop { self.stops.borrow_mut().push(CanvasGradientStop {

View file

@ -105,7 +105,9 @@ impl CSSMethods<crate::DomTypeHolder> for CSS {
RegisterPropertyError::InvalidSyntax | RegisterPropertyError::InvalidSyntax |
RegisterPropertyError::InvalidInitialValue | RegisterPropertyError::InvalidInitialValue |
RegisterPropertyError::NoInitialValue | RegisterPropertyError::NoInitialValue |
RegisterPropertyError::InitialValueNotComputationallyIndependent => Error::Syntax, RegisterPropertyError::InitialValueNotComputationallyIndependent => {
Error::Syntax(None)
},
RegisterPropertyError::AlreadyRegistered => Error::InvalidModification, RegisterPropertyError::AlreadyRegistered => Error::InvalidModification,
})?; })?;

View file

@ -35,7 +35,7 @@ unsafe_no_jsmanaged_fields!(RulesSource);
impl Convert<Error> for RulesMutateError { impl Convert<Error> for RulesMutateError {
fn convert(self) -> Error { fn convert(self) -> Error {
match self { match self {
RulesMutateError::Syntax => Error::Syntax, RulesMutateError::Syntax => Error::Syntax(None),
RulesMutateError::IndexSize => Error::IndexSize, RulesMutateError::IndexSize => Error::IndexSize,
RulesMutateError::HierarchyRequest => Error::HierarchyRequest, RulesMutateError::HierarchyRequest => Error::HierarchyRequest,
RulesMutateError::InvalidState => Error::InvalidState, RulesMutateError::InvalidState => Error::InvalidState,

View file

@ -360,7 +360,7 @@ impl CustomElementRegistryMethods<crate::DomTypeHolder> for CustomElementRegistr
// Step 2. If name is not a valid custom element name, then throw a "SyntaxError" DOMException. // Step 2. If name is not a valid custom element name, then throw a "SyntaxError" DOMException.
if !is_valid_custom_element_name(&name) { if !is_valid_custom_element_name(&name) {
return Err(Error::Syntax); return Err(Error::Syntax(None));
} }
// Step 3. If this's custom element definition set contains an item with name name, // Step 3. If this's custom element definition set contains an item with name name,

View file

@ -236,7 +236,7 @@ impl DissimilarOriginWindow {
"/" => Some(source_origin.clone()), "/" => Some(source_origin.clone()),
url => match ServoUrl::parse(url) { url => match ServoUrl::parse(url) {
Ok(url) => Some(url.origin().clone()), Ok(url) => Some(url.origin().clone()),
Err(_) => return Err(Error::Syntax), Err(_) => return Err(Error::Syntax(None)),
}, },
}; };
let msg = ScriptToConstellationMessage::PostMessage { let msg = ScriptToConstellationMessage::PostMessage {

View file

@ -1196,12 +1196,12 @@ pub(crate) fn transform_to_matrix(value: String) -> Fallible<(bool, Transform3D<
let transform = match parser.parse_entirely(|t| transform::parse(&context, t)) { let transform = match parser.parse_entirely(|t| transform::parse(&context, t)) {
Ok(result) => result, Ok(result) => result,
Err(..) => return Err(error::Error::Syntax), Err(..) => return Err(error::Error::Syntax(None)),
}; };
let (m, is_3d) = match transform.to_transform_3d_matrix_f64(None) { let (m, is_3d) = match transform.to_transform_3d_matrix_f64(None) {
Ok(result) => result, Ok(result) => result,
Err(..) => return Err(error::Error::Syntax), Err(..) => return Err(error::Error::Syntax(None)),
}; };
Ok((!is_3d, m)) Ok((!is_3d, m))

View file

@ -64,7 +64,7 @@ impl DOMTokenList {
fn check_token_exceptions(&self, token: &str) -> Fallible<Atom> { fn check_token_exceptions(&self, token: &str) -> Fallible<Atom> {
match token { match token {
"" => Err(Error::Syntax), "" => Err(Error::Syntax(None)),
slice if slice.find(HTML_SPACE_CHARACTERS).is_some() => Err(Error::InvalidCharacter), slice if slice.find(HTML_SPACE_CHARACTERS).is_some() => Err(Error::InvalidCharacter),
slice => Ok(Atom::from(slice)), slice => Ok(Atom::from(slice)),
} }
@ -190,7 +190,7 @@ impl DOMTokenListMethods<crate::DomTypeHolder> for DOMTokenList {
fn Replace(&self, token: DOMString, new_token: DOMString, can_gc: CanGc) -> Fallible<bool> { fn Replace(&self, token: DOMString, new_token: DOMString, can_gc: CanGc) -> Fallible<bool> {
if token.is_empty() || new_token.is_empty() { if token.is_empty() || new_token.is_empty() {
// Step 1. // Step 1.
return Err(Error::Syntax); return Err(Error::Syntax(None));
} }
if token.contains(HTML_SPACE_CHARACTERS) || new_token.contains(HTML_SPACE_CHARACTERS) { if token.contains(HTML_SPACE_CHARACTERS) || new_token.contains(HTML_SPACE_CHARACTERS) {
// Step 2. // Step 2.

View file

@ -270,7 +270,7 @@ impl FromStr for AdjacentPosition {
"afterbegin" => Ok(AdjacentPosition::AfterBegin), "afterbegin" => Ok(AdjacentPosition::AfterBegin),
"beforeend" => Ok(AdjacentPosition::BeforeEnd), "beforeend" => Ok(AdjacentPosition::BeforeEnd),
"afterend" => Ok(AdjacentPosition::AfterEnd), "afterend" => Ok(AdjacentPosition::AfterEnd),
_ => Err(Error::Syntax) _ => Err(Error::Syntax(None))
} }
} }
} }
@ -4068,7 +4068,7 @@ impl ElementMethods<crate::DomTypeHolder> for Element {
&selectors, &selectors,
&UrlExtraData(url.get_arc()), &UrlExtraData(url.get_arc()),
) { ) {
Err(_) => return Err(Error::Syntax), Err(_) => return Err(Error::Syntax(None)),
Ok(selectors) => selectors, Ok(selectors) => selectors,
}; };
@ -4095,7 +4095,7 @@ impl ElementMethods<crate::DomTypeHolder> for Element {
&selectors, &selectors,
&UrlExtraData(url.get_arc()), &UrlExtraData(url.get_arc()),
) { ) {
Err(_) => return Err(Error::Syntax), Err(_) => return Err(Error::Syntax(None)),
Ok(selectors) => selectors, Ok(selectors) => selectors,
}; };

View file

@ -570,7 +570,7 @@ impl EventSourceMethods<crate::DomTypeHolder> for EventSource {
let url_record = match base_url.join(&url) { let url_record = match base_url.join(&url) {
Ok(u) => u, Ok(u) => u,
// Step 4 If urlRecord is failure, then throw a "SyntaxError" DOMException. // Step 4 If urlRecord is failure, then throw a "SyntaxError" DOMException.
Err(_) => return Err(Error::Syntax), Err(_) => return Err(Error::Syntax(None)),
}; };
// Step 1 Let ev be a new EventSource object. // Step 1 Let ev be a new EventSource object.
let ev = EventSource::new( let ev = EventSource::new(

View file

@ -150,7 +150,7 @@ fn parse_font_face_descriptors(
if error_reporter.not_encountered_error.get() { if error_reporter.not_encountered_error.get() {
Ok(parsed_font_face_rule) Ok(parsed_font_face_rule)
} else { } else {
Err(Error::Syntax) Err(Error::Syntax(None))
} }
} }
@ -191,7 +191,7 @@ impl FontFace {
let font_status_promise = Promise::new(global, can_gc); let font_status_promise = Promise::new(global, can_gc);
// If any of them fail to parse correctly, reject font faces [[FontStatusPromise]] with a // If any of them fail to parse correctly, reject font faces [[FontStatusPromise]] with a
// DOMException named "SyntaxError" // DOMException named "SyntaxError"
font_status_promise.reject_error(Error::Syntax, can_gc); font_status_promise.reject_error(Error::Syntax(None), can_gc);
// set font faces corresponding attributes to the empty string, and set font faces status // set font faces corresponding attributes to the empty string, and set font faces status
// attribute to "error" // attribute to "error"

View file

@ -757,7 +757,7 @@ impl HTMLElement {
.nth(1) .nth(1)
.is_some_and(|ch| ch.is_ascii_lowercase()) .is_some_and(|ch| ch.is_ascii_lowercase())
{ {
return Err(Error::Syntax); return Err(Error::Syntax(None));
} }
self.as_element() self.as_element()
.set_custom_attribute(to_snake_case(name), value, can_gc) .set_custom_attribute(to_snake_case(name), value, can_gc)

View file

@ -212,7 +212,7 @@ impl IDBDatabaseMethods<crate::DomTypeHolder> for IDBDatabase {
// Step 5 // Step 5
if let Some(path) = key_path { if let Some(path) = key_path {
if !is_valid_key_path(path) { if !is_valid_key_path(path) {
return Err(Error::Syntax); return Err(Error::Syntax(None));
} }
} }

View file

@ -138,7 +138,7 @@ impl IntersectionObserver {
let root_margin = if let Ok(margin) = parse_a_margin(init.rootMargin.as_ref()) { let root_margin = if let Ok(margin) = parse_a_margin(init.rootMargin.as_ref()) {
margin margin
} else { } else {
return Err(Error::Syntax); return Err(Error::Syntax(None));
}; };
// Step 4. // Step 4.
@ -147,7 +147,7 @@ impl IntersectionObserver {
let scroll_margin = if let Ok(margin) = parse_a_margin(init.scrollMargin.as_ref()) { let scroll_margin = if let Ok(margin) = parse_a_margin(init.scrollMargin.as_ref()) {
margin margin
} else { } else {
return Err(Error::Syntax); return Err(Error::Syntax(None));
}; };
// Step 1 and step 2, 3, 4 setter // Step 1 and step 2, 3, 4 setter

View file

@ -274,7 +274,7 @@ impl LocationMethods<crate::DomTypeHolder> for Location {
let base_url = self.entry_settings_object().api_base_url(); let base_url = self.entry_settings_object().api_base_url();
let url = match base_url.join(&url.0) { let url = match base_url.join(&url.0) {
Ok(url) => url, Ok(url) => url,
Err(_) => return Err(Error::Syntax), Err(_) => return Err(Error::Syntax(None)),
}; };
Ok(Some(url)) Ok(Some(url))
@ -304,7 +304,7 @@ impl LocationMethods<crate::DomTypeHolder> for Location {
let base_url = self.entry_settings_object().api_base_url(); let base_url = self.entry_settings_object().api_base_url();
let url = match base_url.join(&url.0) { let url = match base_url.join(&url.0) {
Ok(url) => url, Ok(url) => url,
Err(_) => return Err(Error::Syntax), Err(_) => return Err(Error::Syntax(None)),
}; };
// Step 3: Location-object navigate to the resulting URL record with // Step 3: Location-object navigate to the resulting URL record with
// the replacement flag set. // the replacement flag set.
@ -504,7 +504,7 @@ impl LocationMethods<crate::DomTypeHolder> for Location {
if copy_url.as_mut_url().set_scheme(scheme).is_err() { if copy_url.as_mut_url().set_scheme(scheme).is_err() {
// Step 5: If possibleFailure is failure, then throw a "SyntaxError" DOMException. // Step 5: If possibleFailure is failure, then throw a "SyntaxError" DOMException.
return Err(Error::Syntax); return Err(Error::Syntax(None));
} }
// Step 6: If copyURL's scheme is not an HTTP(S) scheme, then terminate these steps. // Step 6: If copyURL's scheme is not an HTTP(S) scheme, then terminate these steps.

View file

@ -1131,7 +1131,7 @@ impl Node {
&UrlExtraData(doc.url().get_arc()), &UrlExtraData(doc.url().get_arc()),
) { ) {
// Step 2. // Step 2.
Err(_) => Err(Error::Syntax), Err(_) => Err(Error::Syntax(None)),
// Step 3. // Step 3.
Ok(selectors) => { Ok(selectors) => {
let mut nth_index_cache = Default::default(); let mut nth_index_cache = Default::default();
@ -1168,7 +1168,7 @@ impl Node {
&UrlExtraData(url.get_arc()), &UrlExtraData(url.get_arc()),
) { ) {
// Step 2. // Step 2.
Err(_) => Err(Error::Syntax), Err(_) => Err(Error::Syntax(None)),
// Step 3. // Step 3.
Ok(selectors) => { Ok(selectors) => {
let mut descendants = self.traverse_preorder(ShadowIncluding::No); let mut descendants = self.traverse_preorder(ShadowIncluding::No);

View file

@ -490,7 +490,7 @@ impl PerformanceMethods<crate::DomTypeHolder> for Performance {
let global = self.global(); let global = self.global();
// Step 1. // Step 1.
if global.is::<Window>() && INVALID_ENTRY_NAMES.contains(&mark_name.as_ref()) { if global.is::<Window>() && INVALID_ENTRY_NAMES.contains(&mark_name.as_ref()) {
return Err(Error::Syntax); return Err(Error::Syntax(None));
} }
// Steps 2 to 6. // Steps 2 to 6.

View file

@ -160,12 +160,12 @@ impl PerformanceObserverMethods<crate::DomTypeHolder> for PerformanceObserver {
// Step 3 // Step 3
if options.entryTypes.is_none() && options.type_.is_none() { if options.entryTypes.is_none() && options.type_.is_none() {
return Err(Error::Syntax); return Err(Error::Syntax(None));
} }
// Step 4 // Step 4
if options.entryTypes.is_some() && (options.buffered.is_some() || options.type_.is_some()) { if options.entryTypes.is_some() && (options.buffered.is_some() || options.type_.is_some()) {
return Err(Error::Syntax); return Err(Error::Syntax(None));
} }
// If this point is reached, then one of options.entryTypes or options.type_ // If this point is reached, then one of options.entryTypes or options.type_

View file

@ -647,7 +647,7 @@ impl SubtleCryptoMethods<crate::DomTypeHolder> for SubtleCrypto {
// Step 17. If the [[type]] internal slot of result is "secret" or "private" and usages // Step 17. If the [[type]] internal slot of result is "secret" or "private" and usages
// is empty, then throw a SyntaxError. // is empty, then throw a SyntaxError.
if matches!(result.Type(), KeyType::Secret | KeyType::Private) && result.usages().is_empty() { if matches!(result.Type(), KeyType::Secret | KeyType::Private) && result.usages().is_empty() {
promise.reject_error(Error::Syntax, CanGc::note()); promise.reject_error(Error::Syntax(None), CanGc::note());
return; return;
} }
@ -759,7 +759,7 @@ impl SubtleCryptoMethods<crate::DomTypeHolder> for SubtleCrypto {
let data_string = match json_web_key.k { let data_string = match json_web_key.k {
Some(s) => s.to_string(), Some(s) => s.to_string(),
None => { None => {
promise.reject_error(Error::Syntax, can_gc); promise.reject_error(Error::Syntax(None), can_gc);
return promise; return promise;
}, },
}; };
@ -769,7 +769,7 @@ impl SubtleCryptoMethods<crate::DomTypeHolder> for SubtleCrypto {
{ {
Ok(data) => data, Ok(data) => data,
Err(_) => { Err(_) => {
promise.reject_error(Error::Syntax, can_gc); promise.reject_error(Error::Syntax(None), can_gc);
return promise; return promise;
}, },
} }
@ -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 // TODO: Support more than just a subset of the JWK dict, or find a way to
// stringify via SM internals // stringify via SM internals
let Some(k) = key.k else { let Some(k) = key.k else {
promise.reject_error(Error::Syntax, CanGc::note()); promise.reject_error(Error::Syntax(None), CanGc::note());
return; return;
}; };
let Some(alg) = key.alg else { let Some(alg) = key.alg else {
promise.reject_error(Error::Syntax, CanGc::note()); promise.reject_error(Error::Syntax(None), CanGc::note());
return; return;
}; };
let Some(ext) = key.ext else { let Some(ext) = key.ext else {
promise.reject_error(Error::Syntax, CanGc::note()); promise.reject_error(Error::Syntax(None), CanGc::note());
return; return;
}; };
let Some(key_ops) = key.key_ops else { let Some(key_ops) = key.key_ops else {
promise.reject_error(Error::Syntax, CanGc::note()); promise.reject_error(Error::Syntax(None), CanGc::note());
return; return;
}; };
let key_ops_str = key_ops.iter().map(|op| op.to_string()).collect::<Vec<String>>(); let key_ops_str = key_ops.iter().map(|op| op.to_string()).collect::<Vec<String>>();
@ -1405,7 +1405,7 @@ macro_rules! value_from_js_object {
($t: ty, $cx: ident, $value: ident) => {{ ($t: ty, $cx: ident, $value: ident) => {{
let params_result = <$t>::new($cx, $value.handle()).map_err(|_| Error::JSFailed)?; let params_result = <$t>::new($cx, $value.handle()).map_err(|_| Error::JSFailed)?;
let ConversionResult::Success(params) = params_result else { let ConversionResult::Success(params) = params_result else {
return Err(Error::Syntax); return Err(Error::Syntax(None));
}; };
params params
}}; }};
@ -1639,21 +1639,21 @@ fn normalize_algorithm_for_key_wrap(
ALG_AES_KW => KeyWrapAlgorithm::AesKw, ALG_AES_KW => KeyWrapAlgorithm::AesKw,
ALG_AES_CBC => { ALG_AES_CBC => {
let AlgorithmIdentifier::Object(obj) = algorithm else { let AlgorithmIdentifier::Object(obj) = algorithm else {
return Err(Error::Syntax); return Err(Error::Syntax(None));
}; };
rooted!(in(*cx) let value = ObjectValue(obj.get())); rooted!(in(*cx) let value = ObjectValue(obj.get()));
KeyWrapAlgorithm::AesCbc(value_from_js_object!(AesCbcParams, cx, value).into()) KeyWrapAlgorithm::AesCbc(value_from_js_object!(AesCbcParams, cx, value).into())
}, },
ALG_AES_CTR => { ALG_AES_CTR => {
let AlgorithmIdentifier::Object(obj) = algorithm else { let AlgorithmIdentifier::Object(obj) = algorithm else {
return Err(Error::Syntax); return Err(Error::Syntax(None));
}; };
rooted!(in(*cx) let value = ObjectValue(obj.get())); rooted!(in(*cx) let value = ObjectValue(obj.get()));
KeyWrapAlgorithm::AesCtr(value_from_js_object!(AesCtrParams, cx, value).into()) KeyWrapAlgorithm::AesCtr(value_from_js_object!(AesCtrParams, cx, value).into())
}, },
ALG_AES_GCM => { ALG_AES_GCM => {
let AlgorithmIdentifier::Object(obj) = algorithm else { let AlgorithmIdentifier::Object(obj) = algorithm else {
return Err(Error::Syntax); return Err(Error::Syntax(None));
}; };
rooted!(in(*cx) let value = ObjectValue(obj.get())); rooted!(in(*cx) let value = ObjectValue(obj.get()));
KeyWrapAlgorithm::AesGcm(value_from_js_object!(AesGcmParams, cx, value).into()) KeyWrapAlgorithm::AesGcm(value_from_js_object!(AesGcmParams, cx, value).into())
@ -2066,7 +2066,7 @@ impl SubtleCrypto {
) )
}) || usages.is_empty() }) || usages.is_empty()
{ {
return Err(Error::Syntax); return Err(Error::Syntax(None));
} }
}, },
ALG_AES_KW => { ALG_AES_KW => {
@ -2075,7 +2075,7 @@ impl SubtleCrypto {
.any(|usage| !matches!(usage, KeyUsage::WrapKey | KeyUsage::UnwrapKey)) || .any(|usage| !matches!(usage, KeyUsage::WrapKey | KeyUsage::UnwrapKey)) ||
usages.is_empty() usages.is_empty()
{ {
return Err(Error::Syntax); return Err(Error::Syntax(None));
} }
}, },
_ => return Err(Error::NotSupported), _ => return Err(Error::NotSupported),
@ -2128,7 +2128,7 @@ impl SubtleCrypto {
.iter() .iter()
.any(|usage| !matches!(usage, KeyUsage::Sign | KeyUsage::Verify)) .any(|usage| !matches!(usage, KeyUsage::Sign | KeyUsage::Verify))
{ {
return Err(Error::Syntax); return Err(Error::Syntax(None));
} }
// Step 2. // Step 2.
@ -2213,7 +2213,7 @@ impl SubtleCrypto {
) )
}) || usages.is_empty() }) || usages.is_empty()
{ {
return Err(Error::Syntax); return Err(Error::Syntax(None));
} }
if !matches!(format, KeyFormat::Raw | KeyFormat::Jwk) { if !matches!(format, KeyFormat::Raw | KeyFormat::Jwk) {
return Err(Error::NotSupported); return Err(Error::NotSupported);
@ -2326,12 +2326,12 @@ impl SubtleCrypto {
.any(|usage| !matches!(usage, KeyUsage::DeriveKey | KeyUsage::DeriveBits)) || .any(|usage| !matches!(usage, KeyUsage::DeriveKey | KeyUsage::DeriveBits)) ||
usages.is_empty() usages.is_empty()
{ {
return Err(Error::Syntax); return Err(Error::Syntax(None));
} }
// Step 2. If extractable is not false, then throw a SyntaxError. // Step 2. If extractable is not false, then throw a SyntaxError.
if extractable { if extractable {
return Err(Error::Syntax); return Err(Error::Syntax(None));
} }
// Step 3. Let key be a new CryptoKey representing the key data provided in keyData. // Step 3. Let key be a new CryptoKey representing the key data provided in keyData.
@ -2383,7 +2383,7 @@ impl SubtleCrypto {
.any(|usage| !matches!(usage, KeyUsage::Sign | KeyUsage::Verify)) || .any(|usage| !matches!(usage, KeyUsage::Sign | KeyUsage::Verify)) ||
usages.is_empty() usages.is_empty()
{ {
return Err(Error::Syntax); return Err(Error::Syntax(None));
} }
// Step 3. Let hash be a new KeyAlgorithm. // Step 3. Let hash be a new KeyAlgorithm.
@ -2592,12 +2592,12 @@ impl SubtleCrypto {
.any(|usage| !matches!(usage, KeyUsage::DeriveKey | KeyUsage::DeriveBits)) || .any(|usage| !matches!(usage, KeyUsage::DeriveKey | KeyUsage::DeriveBits)) ||
usages.is_empty() usages.is_empty()
{ {
return Err(Error::Syntax); return Err(Error::Syntax(None));
} }
// Step 3. If extractable is not false, then throw a SyntaxError. // Step 3. If extractable is not false, then throw a SyntaxError.
if extractable { if extractable {
return Err(Error::Syntax); return Err(Error::Syntax(None));
} }
// Step 4. Let key be a new CryptoKey representing keyData. // Step 4. Let key be a new CryptoKey representing keyData.

View file

@ -369,7 +369,7 @@ impl RTCDataChannelMethods<crate::DomTypeHolder> for RTCDataChannel {
// https://www.w3.org/TR/webrtc/#dom-datachannel-binarytype // https://www.w3.org/TR/webrtc/#dom-datachannel-binarytype
fn SetBinaryType(&self, value: DOMString) -> Fallible<()> { fn SetBinaryType(&self, value: DOMString) -> Fallible<()> {
if value != "blob" || value != "arraybuffer" { if value != "blob" || value != "arraybuffer" {
return Err(Error::Syntax); return Err(Error::Syntax(None));
} }
*self.binary_type.borrow_mut() = value; *self.binary_type.borrow_mut() = value;
Ok(()) Ok(())

View file

@ -190,7 +190,7 @@ impl WebSocketMethods<crate::DomTypeHolder> for WebSocket {
// Step 1. Let baseURL be this's relevant settings object's API base URL. // Step 1. Let baseURL be this's relevant settings object's API base URL.
// Step 2. Let urlRecord be the result of applying the URL parser to url with baseURL. // Step 2. Let urlRecord be the result of applying the URL parser to url with baseURL.
// Step 3. If urlRecord is failure, then throw a "SyntaxError" DOMException. // Step 3. If urlRecord is failure, then throw a "SyntaxError" DOMException.
let mut url_record = ServoUrl::parse(&url).or(Err(Error::Syntax))?; let mut url_record = ServoUrl::parse(&url).or(Err(Error::Syntax(None)))?;
// Step 4. If urlRecords scheme is "http", then set urlRecords scheme to "ws". // Step 4. If urlRecords scheme is "http", then set urlRecords scheme to "ws".
// Step 5. Otherwise, if urlRecords scheme is "https", set urlRecords scheme to "wss". // Step 5. Otherwise, if urlRecords scheme is "https", set urlRecords scheme to "wss".
@ -209,12 +209,12 @@ impl WebSocketMethods<crate::DomTypeHolder> for WebSocket {
.expect("Can't set scheme from https to wss"); .expect("Can't set scheme from https to wss");
}, },
"ws" | "wss" => {}, "ws" | "wss" => {},
_ => return Err(Error::Syntax), _ => return Err(Error::Syntax(None)),
} }
// Step 7. If urlRecords fragment is non-null, then throw a "SyntaxError" DOMException. // Step 7. If urlRecords fragment is non-null, then throw a "SyntaxError" DOMException.
if url_record.fragment().is_some() { if url_record.fragment().is_some() {
return Err(Error::Syntax); return Err(Error::Syntax(None));
} }
// Step 8. If protocols is a string, set protocols to a sequence consisting of just that string. // Step 8. If protocols is a string, set protocols to a sequence consisting of just that string.
@ -236,12 +236,12 @@ impl WebSocketMethods<crate::DomTypeHolder> for WebSocket {
.iter() .iter()
.any(|p| p.eq_ignore_ascii_case(protocol)) .any(|p| p.eq_ignore_ascii_case(protocol))
{ {
return Err(Error::Syntax); return Err(Error::Syntax(None));
} }
// https://tools.ietf.org/html/rfc6455#section-4.1 // https://tools.ietf.org/html/rfc6455#section-4.1
if !is_token(protocol.as_bytes()) { if !is_token(protocol.as_bytes()) {
return Err(Error::Syntax); return Err(Error::Syntax(None));
} }
} }
@ -429,7 +429,7 @@ impl WebSocketMethods<crate::DomTypeHolder> for WebSocket {
if let Some(ref reason) = reason { if let Some(ref reason) = reason {
if reason.0.len() > 123 { if reason.0.len() > 123 {
// reason cannot be larger than 123 bytes // reason cannot be larger than 123 bytes
return Err(Error::Syntax); return Err(Error::Syntax(Some("Reason too long".to_string())));
} }
} }

View file

@ -2009,7 +2009,7 @@ impl Window {
"/" => Some(source_origin.clone()), "/" => Some(source_origin.clone()),
url => match ServoUrl::parse(url) { url => match ServoUrl::parse(url) {
Ok(url) => Some(url.origin().clone()), Ok(url) => Some(url.origin().clone()),
Err(_) => return Err(Error::Syntax), Err(_) => return Err(Error::Syntax(None)),
}, },
}; };

View file

@ -536,7 +536,7 @@ impl WindowProxy {
.unwrap(); .unwrap();
let url = match existing_document.url().join(&url) { let url = match existing_document.url().join(&url) {
Ok(url) => url, Ok(url) => url,
Err(_) => return Err(Error::Syntax), Err(_) => return Err(Error::Syntax(None)),
}; };
let referrer = if noreferrer { let referrer = if noreferrer {
Referrer::NoReferrer Referrer::NoReferrer

View file

@ -179,7 +179,7 @@ impl WorkerMethods<crate::DomTypeHolder> for Worker {
// Step 2-4. // Step 2-4.
let worker_url = match global.api_base_url().join(&compliant_script_url) { let worker_url = match global.api_base_url().join(&compliant_script_url) {
Ok(url) => url, Ok(url) => url,
Err(_) => return Err(Error::Syntax), Err(_) => return Err(Error::Syntax(None)),
}; };
let (sender, receiver) = unbounded(); let (sender, receiver) = unbounded();

View file

@ -392,7 +392,7 @@ impl WorkerGlobalScopeMethods<crate::DomTypeHolder> for WorkerGlobalScope {
let url = self.worker_url.borrow().join(&url); let url = self.worker_url.borrow().join(&url);
match url { match url {
Ok(url) => urls.push(url), Ok(url) => urls.push(url),
Err(_) => return Err(Error::Syntax), Err(_) => return Err(Error::Syntax(None)),
}; };
} }

View file

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

View file

@ -366,7 +366,7 @@ impl XMLHttpRequestMethods<crate::DomTypeHolder> for XMLHttpRequest {
Some(parsed_method) => { Some(parsed_method) => {
// Step 3 // Step 3
if !is_token(&method) { if !is_token(&method) {
return Err(Error::Syntax); return Err(Error::Syntax(None));
} }
// Step 2 // Step 2
@ -375,7 +375,7 @@ impl XMLHttpRequestMethods<crate::DomTypeHolder> for XMLHttpRequest {
let mut parsed_url = match base.join(&url.0) { let mut parsed_url = match base.join(&url.0) {
Ok(parsed) => parsed, Ok(parsed) => parsed,
// Step 7 // Step 7
Err(_) => return Err(Error::Syntax), Err(_) => return Err(Error::Syntax(None)),
}; };
// Step 9 // Step 9
@ -424,7 +424,7 @@ impl XMLHttpRequestMethods<crate::DomTypeHolder> for XMLHttpRequest {
// Step 3 // Step 3
// This includes cases where as_str() returns None, and when is_token() returns false, // This includes cases where as_str() returns None, and when is_token() returns false,
// both of which indicate invalid extension method names // both of which indicate invalid extension method names
_ => Err(Error::Syntax), _ => Err(Error::Syntax(None)),
} }
} }
@ -442,10 +442,10 @@ impl XMLHttpRequestMethods<crate::DomTypeHolder> for XMLHttpRequest {
// Step 4: If name is not a header name or value is not a header value, then throw a // Step 4: If name is not a header name or value is not a header value, then throw a
// "SyntaxError" DOMException. // "SyntaxError" DOMException.
if !is_token(&name) || !is_field_value(value) { if !is_token(&name) || !is_field_value(value) {
return Err(Error::Syntax); return Err(Error::Syntax(None));
} }
let name_str = name.as_str().ok_or(Error::Syntax)?; let name_str = name.as_str().ok_or(Error::Syntax(None))?;
// Step 5: If (name, value) is a forbidden request-header, then return. // Step 5: If (name, value) is a forbidden request-header, then return.
if is_forbidden_request_header(name_str, value) { if is_forbidden_request_header(name_str, value) {
@ -885,7 +885,7 @@ impl XMLHttpRequestMethods<crate::DomTypeHolder> for XMLHttpRequest {
Ok(mime) => mime, Ok(mime) => mime,
Err(_) => "application/octet-stream" Err(_) => "application/octet-stream"
.parse::<Mime>() .parse::<Mime>()
.map_err(|_| Error::Syntax)?, .map_err(|_| Error::Syntax(None))?,
}; };
*self.override_mime_type.borrow_mut() = Some(override_mime); *self.override_mime_type.borrow_mut() = Some(override_mime);

View file

@ -70,7 +70,8 @@ impl XPathEvaluatorMethods<crate::DomTypeHolder> for XPathEvaluator {
let window = global.as_window(); let window = global.as_window();
// NB: this function is *not* Fallible according to the spec, so we swallow any parsing errors and // NB: this function is *not* Fallible according to the spec, so we swallow any parsing errors and
// just pass a None as the expression... it's not great. // just pass a None as the expression... it's not great.
let parsed_expression = crate::xpath::parse(&expression).map_err(|_e| Error::Syntax)?; let parsed_expression =
crate::xpath::parse(&expression).map_err(|_e| Error::Syntax(None))?;
Ok(XPathExpression::new( Ok(XPathExpression::new(
window, window,
None, None,
@ -97,7 +98,8 @@ impl XPathEvaluatorMethods<crate::DomTypeHolder> for XPathEvaluator {
) -> Fallible<DomRoot<XPathResult>> { ) -> Fallible<DomRoot<XPathResult>> {
let global = self.global(); let global = self.global();
let window = global.as_window(); let window = global.as_window();
let parsed_expression = crate::xpath::parse(&expression_str).map_err(|_| Error::Syntax)?; let parsed_expression =
crate::xpath::parse(&expression_str).map_err(|_| Error::Syntax(None))?;
let expression = XPathExpression::new(window, None, can_gc, parsed_expression); let expression = XPathExpression::new(window, None, can_gc, parsed_expression);
XPathExpressionMethods::<crate::DomTypeHolder>::Evaluate( XPathExpressionMethods::<crate::DomTypeHolder>::Evaluate(
&*expression, &*expression,

View file

@ -30,7 +30,7 @@ pub enum Error {
/// InvalidStateError DOMException /// InvalidStateError DOMException
InvalidState, InvalidState,
/// SyntaxError DOMException /// SyntaxError DOMException
Syntax, Syntax(Option<String>),
/// NamespaceError DOMException /// NamespaceError DOMException
Namespace, Namespace,
/// InvalidAccessError DOMException /// InvalidAccessError DOMException