Skip to content

Commit 1c3e7f2

Browse files
committed
Add DomExceptionName
1 parent 0b5172e commit 1c3e7f2

File tree

2 files changed

+144
-45
lines changed

2 files changed

+144
-45
lines changed

modules/llrt_abort/src/abort_signal.rs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
use std::sync::{Arc, RwLock};
44

55
use llrt_events::{Emitter, EventEmitter, EventList};
6-
use llrt_exceptions::DOMException;
6+
use llrt_exceptions::{DOMException, DOMExceptionName};
77
use llrt_utils::mc_oneshot;
88
use rquickjs::{
99
class::{Trace, Tracer},
@@ -160,7 +160,11 @@ impl<'js> AbortSignal<'js> {
160160
pub fn send_aborted(this: This<Class<'js, Self>>, ctx: Ctx<'js>) -> Result<()> {
161161
let mut borrow = this.borrow_mut();
162162
borrow.aborted = true;
163-
let reason = get_reason_or_dom_exception(&ctx, borrow.reason.as_ref(), "AbortError")?;
163+
let reason = get_reason_or_dom_exception(
164+
&ctx,
165+
borrow.reason.as_ref(),
166+
DOMExceptionName::AbortError,
167+
)?;
164168
borrow.reason = Some(reason.clone());
165169
borrow.sender.send(reason);
166170
drop(borrow);
@@ -179,7 +183,8 @@ impl<'js> AbortSignal<'js> {
179183

180184
#[qjs(static)]
181185
pub fn timeout(ctx: Ctx<'js>, milliseconds: u64) -> Result<Class<'js, Self>> {
182-
let timeout_error = get_reason_or_dom_exception(&ctx, None, "TimeoutError")?;
186+
let timeout_error =
187+
get_reason_or_dom_exception(&ctx, None, DOMExceptionName::TimeoutError)?;
183188

184189
let signal = Self::new();
185190
let signal_instance = Class::instance(ctx.clone(), signal)?;
@@ -221,12 +226,12 @@ impl<'js> AbortSignal<'js> {
221226
fn get_reason_or_dom_exception<'js>(
222227
ctx: &Ctx<'js>,
223228
reason: Option<&Value<'js>>,
224-
name: &str,
229+
name: DOMExceptionName,
225230
) -> Result<Value<'js>> {
226231
let reason = if let Some(reason) = reason {
227232
reason.clone()
228233
} else {
229-
let ex = DOMException::new(ctx.clone(), Opt(None), Opt(Some(name.into())))?;
234+
let ex = DOMException::new_with_name(ctx, name, String::new())?;
230235
Class::instance(ctx.clone(), ex)?.into_value()
231236
};
232237
Ok(reason)

modules/llrt_exceptions/src/lib.rs

Lines changed: 134 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -6,56 +6,64 @@ use rquickjs::{atom::PredefinedAtom, function::Opt, Class, Ctx, Object, Result};
66
#[rquickjs::class]
77
#[derive(rquickjs::class::Trace, rquickjs::JsLifetime)]
88
pub struct DOMException {
9+
name: DOMExceptionName,
910
message: String,
10-
name: String,
1111
stack: String,
12-
code: u8,
12+
}
13+
14+
// https://webidl.spec.whatwg.org/#dfn-error-names-table
15+
#[derive(rquickjs::class::Trace, Debug)]
16+
pub enum DOMExceptionName {
17+
IndexSizeError,
18+
HierarchyRequestError,
19+
WrongDocumentError,
20+
InvalidCharacterError,
21+
NoModificationAllowedError,
22+
NotFoundError,
23+
NotSupportedError,
24+
InUseAttributeError,
25+
InvalidStateError,
26+
SyntaxError,
27+
InvalidModificationError,
28+
NamespaceError,
29+
InvalidAccessError,
30+
TypeMismatchError,
31+
SecurityError,
32+
NetworkError,
33+
AbortError,
34+
URLMismatchError,
35+
QuotaExceededError,
36+
TimeoutError,
37+
InvalidNodeTypeError,
38+
DataCloneError,
39+
Error,
40+
Other(String),
1341
}
1442

1543
#[rquickjs::methods]
1644
impl DOMException {
1745
#[qjs(constructor)]
1846
pub fn new(ctx: Ctx<'_>, message: Opt<String>, name: Opt<String>) -> Result<Self> {
19-
let primordials = BasePrimordials::get(&ctx)?;
47+
let message = message.0.unwrap_or_default();
48+
let name = name
49+
.0
50+
.map(DOMExceptionName::from)
51+
.unwrap_or(DOMExceptionName::Error);
52+
53+
Self::new_with_name(&ctx, name, message)
54+
}
55+
56+
#[qjs(skip)]
57+
pub fn new_with_name(ctx: &Ctx<'_>, name: DOMExceptionName, message: String) -> Result<Self> {
58+
let primordials = BasePrimordials::get(ctx)?;
2059

2160
let new: Object = primordials
2261
.constructor_error
2362
.construct((message.clone(),))?;
2463

25-
let message = message.0.unwrap_or(String::from(""));
26-
let name = name.0.unwrap_or(String::from("Error"));
27-
28-
// https://webidl.spec.whatwg.org/#dfn-error-names-table
29-
let code = match name.as_str() {
30-
"IndexSizeError" => 1,
31-
"HierarchyRequestError" => 3,
32-
"WrongDocumentError" => 4,
33-
"InvalidCharacterError" => 5,
34-
"NoModificationAllowedError" => 7,
35-
"NotFoundError" => 8,
36-
"NotSupportedError" => 9,
37-
"InUseAttributeError" => 10,
38-
"InvalidStateError" => 11,
39-
"SyntaxError" => 12,
40-
"InvalidModificationError" => 13,
41-
"NamespaceError" => 14,
42-
"InvalidAccessError" => 15,
43-
"TypeMismatchError" => 17,
44-
"SecurityError" => 18,
45-
"NetworkError" => 19,
46-
"AbortError" => 20,
47-
"URLMismatchError" => 21,
48-
"QuotaExceededError" => 22,
49-
"TimeoutError" => 23,
50-
"InvalidNodeTypeError" => 24,
51-
"DataCloneError" => 25,
52-
_ => 0,
53-
};
54-
5564
Ok(Self {
56-
message,
5765
name,
58-
code,
66+
message,
5967
stack: new.get::<_, String>(PredefinedAtom::Stack)?,
6068
})
6169
}
@@ -66,13 +74,38 @@ impl DOMException {
6674
}
6775

6876
#[qjs(get)]
69-
pub fn name(&self) -> String {
70-
self.name.clone()
77+
pub fn name(&self) -> &str {
78+
self.name.as_str()
7179
}
7280

7381
#[qjs(get)]
7482
pub fn code(&self) -> u8 {
75-
self.code
83+
match self.name {
84+
DOMExceptionName::IndexSizeError => 1,
85+
DOMExceptionName::HierarchyRequestError => 3,
86+
DOMExceptionName::WrongDocumentError => 4,
87+
DOMExceptionName::InvalidCharacterError => 5,
88+
DOMExceptionName::NoModificationAllowedError => 7,
89+
DOMExceptionName::NotFoundError => 8,
90+
DOMExceptionName::NotSupportedError => 9,
91+
DOMExceptionName::InUseAttributeError => 10,
92+
DOMExceptionName::InvalidStateError => 11,
93+
DOMExceptionName::SyntaxError => 12,
94+
DOMExceptionName::InvalidModificationError => 13,
95+
DOMExceptionName::NamespaceError => 14,
96+
DOMExceptionName::InvalidAccessError => 15,
97+
DOMExceptionName::TypeMismatchError => 17,
98+
DOMExceptionName::SecurityError => 18,
99+
DOMExceptionName::NetworkError => 19,
100+
DOMExceptionName::AbortError => 20,
101+
DOMExceptionName::URLMismatchError => 21,
102+
DOMExceptionName::QuotaExceededError => 22,
103+
DOMExceptionName::TimeoutError => 23,
104+
DOMExceptionName::InvalidNodeTypeError => 24,
105+
DOMExceptionName::DataCloneError => 25,
106+
DOMExceptionName::Error => 0,
107+
DOMExceptionName::Other(_) => 0,
108+
}
76109
}
77110

78111
#[qjs(get)]
@@ -84,10 +117,71 @@ impl DOMException {
84117
#[qjs(rename = PredefinedAtom::ToString)]
85118
pub fn to_string(&self) -> String {
86119
if self.message.is_empty() {
87-
return self.name.clone();
120+
return self.name().to_string();
88121
}
89122

90-
[self.name.as_str(), self.message.as_str()].join(": ")
123+
[self.name(), self.message.as_str()].join(": ")
124+
}
125+
}
126+
127+
impl From<String> for DOMExceptionName {
128+
fn from(value: String) -> Self {
129+
match value.as_str() {
130+
"IndexSizeError" => DOMExceptionName::IndexSizeError,
131+
"HierarchyRequestError" => DOMExceptionName::HierarchyRequestError,
132+
"WrongDocumentError" => DOMExceptionName::WrongDocumentError,
133+
"InvalidCharacterError" => DOMExceptionName::InvalidCharacterError,
134+
"NoModificationAllowedError" => DOMExceptionName::NoModificationAllowedError,
135+
"NotFoundError" => DOMExceptionName::NotFoundError,
136+
"NotSupportedError" => DOMExceptionName::NotSupportedError,
137+
"InUseAttributeError" => DOMExceptionName::InUseAttributeError,
138+
"InvalidStateError" => DOMExceptionName::InvalidStateError,
139+
"SyntaxError" => DOMExceptionName::SyntaxError,
140+
"InvalidModificationError" => DOMExceptionName::InvalidModificationError,
141+
"NamespaceError" => DOMExceptionName::NamespaceError,
142+
"InvalidAccessError" => DOMExceptionName::InvalidAccessError,
143+
"TypeMismatchError" => DOMExceptionName::TypeMismatchError,
144+
"SecurityError" => DOMExceptionName::SecurityError,
145+
"NetworkError" => DOMExceptionName::NetworkError,
146+
"AbortError" => DOMExceptionName::AbortError,
147+
"URLMismatchError" => DOMExceptionName::URLMismatchError,
148+
"QuotaExceededError" => DOMExceptionName::QuotaExceededError,
149+
"TimeoutError" => DOMExceptionName::TimeoutError,
150+
"InvalidNodeTypeError" => DOMExceptionName::InvalidNodeTypeError,
151+
"DataCloneError" => DOMExceptionName::DataCloneError,
152+
_ => DOMExceptionName::Other(value),
153+
}
154+
}
155+
}
156+
157+
impl DOMExceptionName {
158+
fn as_str(&self) -> &str {
159+
match self {
160+
DOMExceptionName::IndexSizeError => "IndexSizeError",
161+
DOMExceptionName::HierarchyRequestError => "HierarchyRequestError",
162+
DOMExceptionName::WrongDocumentError => "WrongDocumentError",
163+
DOMExceptionName::InvalidCharacterError => "InvalidCharacterError",
164+
DOMExceptionName::NoModificationAllowedError => "NoModificationAllowedError",
165+
DOMExceptionName::NotFoundError => "NotFoundError",
166+
DOMExceptionName::NotSupportedError => "NotSupportedError",
167+
DOMExceptionName::InUseAttributeError => "InUseAttributeError",
168+
DOMExceptionName::InvalidStateError => "InvalidStateError",
169+
DOMExceptionName::SyntaxError => "SyntaxError",
170+
DOMExceptionName::InvalidModificationError => "InvalidModificationError",
171+
DOMExceptionName::NamespaceError => "NamespaceError",
172+
DOMExceptionName::InvalidAccessError => "InvalidAccessError",
173+
DOMExceptionName::TypeMismatchError => "TypeMismatchError",
174+
DOMExceptionName::SecurityError => "SecurityError",
175+
DOMExceptionName::NetworkError => "NetworkError",
176+
DOMExceptionName::AbortError => "AbortError",
177+
DOMExceptionName::URLMismatchError => "URLMismatchError",
178+
DOMExceptionName::QuotaExceededError => "QuotaExceededError",
179+
DOMExceptionName::TimeoutError => "TimeoutError",
180+
DOMExceptionName::InvalidNodeTypeError => "InvalidNodeTypeError",
181+
DOMExceptionName::DataCloneError => "DataCloneError",
182+
DOMExceptionName::Error => "Error",
183+
DOMExceptionName::Other(name) => name.as_str(),
184+
}
91185
}
92186
}
93187

0 commit comments

Comments
 (0)