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("The memory does not support atomic operations")]
98 AtomicsNotSupported,
99 #[error("A user-defined error occurred: {0}")]
101 Generic(String),
102}
103
104#[derive(Error, Debug, Clone)]
109pub enum ImportError {
110 #[error("incompatible import type. Expected {0:?} but received {1:?}")]
113 IncompatibleType(ExternType, ExternType),
114
115 #[error("unknown import. Expected {0:?}")]
118 UnknownImport(ExternType),
119
120 #[error("memory error. {0}")]
122 MemoryError(String),
123}
124
125#[derive(Error, Debug)]
128pub enum PreInstantiationError {
129 #[error("module compiled with CPU feature that is missing from host")]
132 CpuFeature(String),
133}
134
135use crate::lib::std::string::String;
136
137#[derive(Debug)]
148#[cfg_attr(feature = "std", derive(Error))]
149pub enum CompileError {
150 #[cfg_attr(feature = "std", error("WebAssembly translation error: {0}"))]
152 Wasm(WasmError),
153
154 #[cfg_attr(feature = "std", error("Compilation error: {0}"))]
156 Codegen(String),
157
158 #[cfg_attr(feature = "std", error("Validation error: {0}"))]
160 Validate(String),
161
162 #[cfg_attr(feature = "std", error("Feature {0} is not yet supported"))]
164 UnsupportedFeature(String),
165
166 #[cfg_attr(
169 feature = "std",
170 error("The target {0} is not yet supported (see https://docs.wasmer.io/runtime/features)")
171 )]
172 UnsupportedTarget(String),
173
174 #[cfg_attr(feature = "std", error("Insufficient resources: {0}"))]
176 Resource(String),
177
178 #[cfg_attr(feature = "std", error("Middleware error: {0}"))]
180 MiddlewareError(String),
181
182 #[cfg_attr(feature = "std", error("Compilation aborted: {0}"))]
184 Aborted(UserAbort),
185}
186
187impl From<WasmError> for CompileError {
188 fn from(original: WasmError) -> Self {
189 Self::Wasm(original)
190 }
191}
192
193impl From<UserAbort> for CompileError {
194 fn from(abort: UserAbort) -> Self {
195 Self::Aborted(abort)
196 }
197}
198
199#[derive(Debug)]
201#[cfg_attr(feature = "std", derive(Error))]
202#[cfg_attr(feature = "std", error("Error in middleware {name}: {message}"))]
203pub struct MiddlewareError {
204 pub name: String,
206 pub message: String,
208}
209
210impl MiddlewareError {
211 pub fn new<A: Into<String>, B: Into<String>>(name: A, message: B) -> Self {
213 Self {
214 name: name.into(),
215 message: message.into(),
216 }
217 }
218}
219
220impl From<MiddlewareError> for CompileError {
221 fn from(error: MiddlewareError) -> Self {
222 WasmError::Middleware(error).into()
223 }
224}
225
226#[derive(Debug)]
231#[cfg_attr(feature = "std", derive(Error))]
232pub enum WasmError {
233 #[cfg_attr(
238 feature = "std",
239 error("Invalid input WebAssembly code at offset {offset}: {message}")
240 )]
241 InvalidWebAssembly {
242 message: String,
244 offset: usize,
246 },
247
248 #[cfg_attr(feature = "std", error("Unsupported feature: {0}"))]
252 Unsupported(String),
253
254 #[cfg_attr(feature = "std", error("Implementation limit exceeded"))]
256 ImplLimitExceeded,
257
258 #[cfg_attr(feature = "std", error("{0}"))]
260 Middleware(MiddlewareError),
261
262 #[cfg_attr(feature = "std", error("{0}"))]
264 Generic(String),
265}
266
267impl From<MiddlewareError> for WasmError {
268 fn from(original: MiddlewareError) -> Self {
269 Self::Middleware(original)
270 }
271}
272
273#[derive(Debug)]
276#[cfg_attr(feature = "std", derive(Error))]
277pub enum ParseCpuFeatureError {
278 #[cfg_attr(feature = "std", error("CpuFeature {0} not recognized"))]
280 Missing(String),
281}
282
283pub type WasmResult<T> = Result<T, WasmError>;
285
286#[cfg(test)]
287mod tests {
288 use super::*;
289
290 #[test]
291 fn middleware_error_can_be_created() {
292 let msg = String::from("Something went wrong");
293 let error = MiddlewareError::new("manipulator3000", msg);
294 assert_eq!(error.name, "manipulator3000");
295 assert_eq!(error.message, "Something went wrong");
296 }
297
298 #[test]
299 fn middleware_error_be_converted_to_wasm_error() {
300 let error = WasmError::from(MiddlewareError::new("manipulator3000", "foo"));
301 match error {
302 WasmError::Middleware(MiddlewareError { name, message }) => {
303 assert_eq!(name, "manipulator3000");
304 assert_eq!(message, "foo");
305 }
306 err => panic!("Unexpected error: {err:?}"),
307 }
308 }
309}