1use std::ffi::CString;
6
7use js::error::throw_type_error;
8use js::jsapi::JS_IsExceptionPending;
9
10use crate::codegen::PrototypeList::proto_id_to_name;
11use crate::num::Finite;
12use crate::script_runtime::JSContext as SafeJSContext;
13
14#[derive(Clone, Debug, MallocSizeOf)]
17pub enum Error {
18 IndexSize(Option<String>),
20 NotFound(Option<String>),
22 HierarchyRequest(Option<String>),
24 WrongDocument(Option<String>),
26 InvalidCharacter(Option<String>),
28 NotSupported(Option<String>),
30 InUseAttribute(Option<String>),
32 InvalidState(Option<String>),
34 Syntax(Option<String>),
36 Namespace(Option<String>),
38 InvalidAccess(Option<String>),
40 Security(Option<String>),
42 Network(Option<String>),
44 Abort(Option<String>),
46 Timeout(Option<String>),
48 InvalidNodeType(Option<String>),
50 DataClone(Option<String>),
52 TransactionInactive(Option<String>),
54 ReadOnly(Option<String>),
56 Version(Option<String>),
58 NoModificationAllowed(Option<String>),
60 QuotaExceeded {
62 quota: Option<Finite<f64>>,
63 requested: Option<Finite<f64>>,
64 },
65 TypeMismatch(Option<String>),
67 InvalidModification(Option<String>),
69 NotReadable(Option<String>),
71 Data(Option<String>),
73 Operation(Option<String>),
75 NotAllowed(Option<String>),
77 Encoding(Option<String>),
79 Constraint(Option<String>),
81
82 Type(CString),
84 Range(CString),
86
87 JSFailed,
89}
90
91pub type Fallible<T> = Result<T, Error>;
93
94pub type ErrorResult = Fallible<()>;
97
98pub fn throw_invalid_this(cx: SafeJSContext, proto_id: u16) {
101 debug_assert!(unsafe { !JS_IsExceptionPending(*cx) });
102 let mut vec = "\"this\" object does not implement interface "
103 .as_bytes()
104 .to_vec();
105 vec.extend_from_slice(proto_id_to_name(proto_id).as_bytes());
106 let error = CString::new(vec).expect("WebIDL name should not contain nul byte");
107 unsafe { throw_type_error(*cx, &error) };
108}
109
110pub fn throw_constructor_without_new(cx: SafeJSContext, name: &str) {
111 debug_assert!(unsafe { !JS_IsExceptionPending(*cx) });
112 let mut error = name.as_bytes().to_vec();
113 error.extend_from_slice(b" constructor: 'new' is required");
114 let error = CString::new(error).expect("WebIDL name should not contain nul byte");
115 unsafe { throw_type_error(*cx, &error) };
116}
117
118#[macro_export]
119macro_rules! cformat {
125 ($($arg:tt)*) => {
126 {
127 use std::io::Write;
128 let mut s = Vec::new();
129 write!(&mut s, $($arg)*).unwrap();
130 std::ffi::CString::new(s).or_else(|s| {
131 let s = s.into_vec();
132 let mut out = Vec::with_capacity(s.len());
133 for b in s {
134 if b == 0 {
135 out.extend_from_slice(b"\\u0000");
136 } else {
137 out.push(b);
138 }
139 }
140 std::ffi::CString::new(out)
141 }).expect("nul bytes should be replaced")
142 }
143 }
144}