1use crate::{ExternType, Pages};
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
183impl From<WasmError> for CompileError {
184    fn from(original: WasmError) -> Self {
185        Self::Wasm(original)
186    }
187}
188
189#[derive(Debug)]
191#[cfg_attr(feature = "std", derive(Error))]
192#[cfg_attr(feature = "std", error("Error in middleware {name}: {message}"))]
193pub struct MiddlewareError {
194    pub name: String,
196    pub message: String,
198}
199
200impl MiddlewareError {
201    pub fn new<A: Into<String>, B: Into<String>>(name: A, message: B) -> Self {
203        Self {
204            name: name.into(),
205            message: message.into(),
206        }
207    }
208}
209
210#[derive(Debug)]
215#[cfg_attr(feature = "std", derive(Error))]
216pub enum WasmError {
217    #[cfg_attr(
222        feature = "std",
223        error("Invalid input WebAssembly code at offset {offset}: {message}")
224    )]
225    InvalidWebAssembly {
226        message: String,
228        offset: usize,
230    },
231
232    #[cfg_attr(feature = "std", error("Unsupported feature: {0}"))]
236    Unsupported(String),
237
238    #[cfg_attr(feature = "std", error("Implementation limit exceeded"))]
240    ImplLimitExceeded,
241
242    #[cfg_attr(feature = "std", error("{0}"))]
244    Middleware(MiddlewareError),
245
246    #[cfg_attr(feature = "std", error("{0}"))]
248    Generic(String),
249}
250
251impl From<MiddlewareError> for WasmError {
252    fn from(original: MiddlewareError) -> Self {
253        Self::Middleware(original)
254    }
255}
256
257#[derive(Debug)]
260#[cfg_attr(feature = "std", derive(Error))]
261pub enum ParseCpuFeatureError {
262    #[cfg_attr(feature = "std", error("CpuFeature {0} not recognized"))]
264    Missing(String),
265}
266
267pub type WasmResult<T> = Result<T, WasmError>;
269
270#[cfg(test)]
271mod tests {
272    use super::*;
273
274    #[test]
275    fn middleware_error_can_be_created() {
276        let msg = String::from("Something went wrong");
277        let error = MiddlewareError::new("manipulator3000", msg);
278        assert_eq!(error.name, "manipulator3000");
279        assert_eq!(error.message, "Something went wrong");
280    }
281
282    #[test]
283    fn middleware_error_be_converted_to_wasm_error() {
284        let error = WasmError::from(MiddlewareError::new("manipulator3000", "foo"));
285        match error {
286            WasmError::Middleware(MiddlewareError { name, message }) => {
287                assert_eq!(name, "manipulator3000");
288                assert_eq!(message, "foo");
289            }
290            err => panic!("Unexpected error: {err:?}"),
291        }
292    }
293}