1use crate::{ExternType, Pages, progress::UserAbort};
3use std::io;
4use thiserror::Error;
5
6#[derive(Error, Debug)]
9pub enum SerializeError {
10 #[error(transparent)]
12 Io(#[from] io::Error),
13 #[error("{0}")]
15 Generic(String),
16}
17
18#[derive(Error, Debug)]
21pub enum DeserializeError {
22 #[error(transparent)]
24 Io(#[from] io::Error),
25 #[error("{0}")]
27 Generic(String),
28 #[error("incompatible binary: {0}")]
30 Incompatible(String),
31 #[error("corrupted binary: {0}")]
33 CorruptedBinary(String),
34 #[error(transparent)]
37 Compiler(#[from] CompileError),
38 #[error("invalid input bytes: expected {expected} bytes, got {got}")]
40 InvalidByteLength {
41 expected: usize,
43 got: usize,
45 },
46}
47
48#[derive(Error, Debug, Clone, PartialEq, Eq, Hash)]
50#[non_exhaustive]
51pub enum MemoryError {
52 #[error("Error when allocating memory: {0}")]
54 Region(String),
55 #[error("The memory could not grow: current size {} pages, requested increase: {} pages", current.0, attempted_delta.0)]
58 CouldNotGrow {
59 current: Pages,
61 attempted_delta: Pages,
63 },
64 #[error("The memory is invalid because {}", reason)]
66 InvalidMemory {
67 reason: String,
69 },
70 #[error("The minimum requested ({} pages) memory is greater than the maximum allowed memory ({} pages)", min_requested.0, max_allowed.0)]
72 MinimumMemoryTooLarge {
73 min_requested: Pages,
75 max_allowed: Pages,
77 },
78 #[error("The maximum requested memory ({} pages) is greater than the maximum allowed memory ({} pages)", max_requested.0, max_allowed.0)]
80 MaximumMemoryTooLarge {
81 max_requested: Pages,
83 max_allowed: Pages,
85 },
86 #[error("The memory is not shared")]
88 MemoryNotShared,
89 #[error("tried to call an unsupported memory operation: {message}")]
92 UnsupportedOperation {
93 message: String,
95 },
96 #[error("Atomic operation failed: {0}")]
98 AtomicOperationFailed(AtomicsError),
99 #[error("A user-defined error occurred: {0}")]
101 Generic(String),
102}
103
104#[derive(PartialEq, Eq, Debug, Error, Clone, Copy, Hash)]
107#[non_exhaustive]
108pub enum AtomicsError {
109 #[error("The memory does not support atomic operations")]
111 Unimplemented,
112 #[error("Too many waiters for address")]
114 TooManyWaiters,
115 #[error("Atomic operations are disabled for this memory")]
117 AtomicsDisabled,
118 #[error("The memory was already dropped")]
120 MemoryDropped,
121}
122
123#[derive(Error, Debug, Clone)]
128pub enum ImportError {
129 #[error("incompatible import type. Expected {0:?} but received {1:?}")]
132 IncompatibleType(ExternType, ExternType),
133
134 #[error("unknown import. Expected {0:?}")]
137 UnknownImport(ExternType),
138
139 #[error("memory error. {0}")]
141 MemoryError(String),
142}
143
144#[derive(Error, Debug)]
147pub enum PreInstantiationError {
148 #[error("module compiled with CPU feature that is missing from host")]
151 CpuFeature(String),
152}
153
154use std::string::String;
155
156#[derive(Error, Debug)]
164pub enum CompileError {
165 #[error("WebAssembly translation error: {0}")]
167 Wasm(WasmError),
168
169 #[error("Compilation error: {0}")]
171 Codegen(String),
172
173 #[error("Validation error: {0}")]
175 Validate(String),
176
177 #[error("Feature {0} is not yet supported")]
179 UnsupportedFeature(String),
180
181 #[error("The target {0} is not yet supported (see https://docs.wasmer.io/runtime/features)")]
184 UnsupportedTarget(String),
185
186 #[error("Insufficient resources: {0}")]
188 Resource(String),
189
190 #[error("Middleware error: {0}")]
192 MiddlewareError(String),
193
194 #[error("Compilation aborted: {0}")]
196 Aborted(UserAbort),
197}
198
199impl From<WasmError> for CompileError {
200 fn from(original: WasmError) -> Self {
201 Self::Wasm(original)
202 }
203}
204
205impl From<UserAbort> for CompileError {
206 fn from(abort: UserAbort) -> Self {
207 Self::Aborted(abort)
208 }
209}
210
211#[derive(Error, Debug)]
213#[error("Error in middleware {name}: {message}")]
214pub struct MiddlewareError {
215 pub name: String,
217 pub message: String,
219}
220
221impl MiddlewareError {
222 pub fn new<A: Into<String>, B: Into<String>>(name: A, message: B) -> Self {
224 Self {
225 name: name.into(),
226 message: message.into(),
227 }
228 }
229}
230
231impl From<MiddlewareError> for CompileError {
232 fn from(error: MiddlewareError) -> Self {
233 WasmError::Middleware(error).into()
234 }
235}
236
237#[derive(Error, Debug)]
242pub enum WasmError {
243 #[error("Invalid input WebAssembly code at offset {offset}: {message}")]
248 InvalidWebAssembly {
249 message: String,
251 offset: usize,
253 },
254
255 #[error("Unsupported feature: {0}")]
259 Unsupported(String),
260
261 #[error("Implementation limit exceeded")]
263 ImplLimitExceeded,
264
265 #[error("{0}")]
267 Middleware(MiddlewareError),
268
269 #[error("{0}")]
271 Generic(String),
272}
273
274impl From<MiddlewareError> for WasmError {
275 fn from(original: MiddlewareError) -> Self {
276 Self::Middleware(original)
277 }
278}
279
280#[derive(Error, Debug)]
283pub enum ParseCpuFeatureError {
284 #[error("CpuFeature {0} not recognized")]
286 Missing(String),
287}
288
289pub type WasmResult<T> = Result<T, WasmError>;
291
292#[cfg(test)]
293mod tests {
294 use super::*;
295
296 #[test]
297 fn middleware_error_can_be_created() {
298 let msg = String::from("Something went wrong");
299 let error = MiddlewareError::new("manipulator3000", msg);
300 assert_eq!(error.name, "manipulator3000");
301 assert_eq!(error.message, "Something went wrong");
302 }
303
304 #[test]
305 fn middleware_error_be_converted_to_wasm_error() {
306 let error = WasmError::from(MiddlewareError::new("manipulator3000", "foo"));
307 match error {
308 WasmError::Middleware(MiddlewareError { name, message }) => {
309 assert_eq!(name, "manipulator3000");
310 assert_eq!(message, "foo");
311 }
312 err => panic!("Unexpected error: {err:?}"),
313 }
314 }
315}