wasmer_compiler/
error.rs

1use crate::lib::std::string::String;
2#[cfg(feature = "std")]
3use thiserror::Error;
4
5// Compilation Errors
6//
7// If `std` feature is enable, we can't use `thiserror` until
8// https://github.com/dtolnay/thiserror/pull/64 is merged.
9
10/// The WebAssembly.CompileError object indicates an error during
11/// WebAssembly decoding or validation.
12///
13/// This is based on the [Wasm Compile Error][compile-error] API.
14///
15/// [compiler-error]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/CompileError
16#[derive(Debug)]
17#[cfg_attr(feature = "std", derive(Error))]
18pub enum CompileError {
19    /// A Wasm translation error occured.
20    #[cfg_attr(feature = "std", error("WebAssembly translation error: {0}"))]
21    Wasm(WasmError),
22
23    /// A compilation error occured.
24    #[cfg_attr(feature = "std", error("Compilation error: {0}"))]
25    Codegen(String),
26
27    /// The module did not pass validation.
28    #[cfg_attr(feature = "std", error("Validation error: {0}"))]
29    Validate(String),
30
31    /// The compiler doesn't support a Wasm feature
32    #[cfg_attr(feature = "std", error("Feature {0} is not yet supported"))]
33    UnsupportedFeature(String),
34
35    /// The compiler cannot compile for the given target.
36    /// This can refer to the OS, the chipset or any other aspect of the target system.
37    #[cfg_attr(feature = "std", error("The target {0} is not yet supported (see https://docs.wasmer.io/ecosystem/wasmer/wasmer-features)"))]
38    UnsupportedTarget(String),
39
40    /// Insufficient resources available for execution.
41    #[cfg_attr(feature = "std", error("Insufficient resources: {0}"))]
42    Resource(String),
43
44    /// Cannot downcast the engine to a specific type.
45    #[cfg_attr(
46        feature = "std",
47        error("cannot downcast the engine to a specific type")
48    )]
49    EngineDowncast,
50}
51
52impl From<WasmError> for CompileError {
53    fn from(original: WasmError) -> Self {
54        Self::Wasm(original)
55    }
56}
57
58/// A error in the middleware.
59#[derive(Debug)]
60#[cfg_attr(feature = "std", derive(Error))]
61#[cfg_attr(feature = "std", error("Error in middleware {name}: {message}"))]
62pub struct MiddlewareError {
63    /// The name of the middleware where the error was created
64    pub name: String,
65    /// The error message
66    pub message: String,
67}
68
69impl MiddlewareError {
70    /// Create a new `MiddlewareError`
71    pub fn new<A: Into<String>, B: Into<String>>(name: A, message: B) -> Self {
72        Self {
73            name: name.into(),
74            message: message.into(),
75        }
76    }
77}
78
79/// A WebAssembly translation error.
80///
81/// When a WebAssembly function can't be translated, one of these error codes will be returned
82/// to describe the failure.
83#[derive(Debug)]
84#[cfg_attr(feature = "std", derive(Error))]
85pub enum WasmError {
86    /// The input WebAssembly code is invalid.
87    ///
88    /// This error code is used by a WebAssembly translator when it encounters invalid WebAssembly
89    /// code. This should never happen for validated WebAssembly code.
90    #[cfg_attr(
91        feature = "std",
92        error("Invalid input WebAssembly code at offset {offset}: {message}")
93    )]
94    InvalidWebAssembly {
95        /// A string describing the validation error.
96        message: String,
97        /// The bytecode offset where the error occurred.
98        offset: usize,
99    },
100
101    /// A feature used by the WebAssembly code is not supported by the embedding environment.
102    ///
103    /// Embedding environments may have their own limitations and feature restrictions.
104    #[cfg_attr(feature = "std", error("Unsupported feature: {0}"))]
105    Unsupported(String),
106
107    /// An implementation limit was exceeded.
108    #[cfg_attr(feature = "std", error("Implementation limit exceeded"))]
109    ImplLimitExceeded,
110
111    /// An error from the middleware error.
112    #[cfg_attr(feature = "std", error("{0}"))]
113    Middleware(MiddlewareError),
114
115    /// A generic error.
116    #[cfg_attr(feature = "std", error("{0}"))]
117    Generic(String),
118}
119
120impl From<MiddlewareError> for WasmError {
121    fn from(original: MiddlewareError) -> Self {
122        Self::Middleware(original)
123    }
124}
125
126/// The error that can happen while parsing a `str`
127/// to retrieve a [`CpuFeature`](crate::target::CpuFeature).
128#[derive(Debug)]
129#[cfg_attr(feature = "std", derive(Error))]
130pub enum ParseCpuFeatureError {
131    /// The provided string feature doesn't exist
132    #[cfg_attr(feature = "std", error("CpuFeature {0} not recognized"))]
133    Missing(String),
134}
135
136/// A convenient alias for a `Result` that uses `WasmError` as the error type.
137pub type WasmResult<T> = Result<T, WasmError>;
138
139#[cfg(test)]
140mod tests {
141    use super::*;
142
143    #[test]
144    fn middleware_error_can_be_created() {
145        let msg = String::from("Something went wrong");
146        let error = MiddlewareError::new("manipulator3000", msg);
147        assert_eq!(error.name, "manipulator3000");
148        assert_eq!(error.message, "Something went wrong");
149    }
150
151    #[test]
152    fn middleware_error_be_converted_to_wasm_error() {
153        let error = WasmError::from(MiddlewareError::new("manipulator3000", "foo"));
154        match error {
155            WasmError::Middleware(MiddlewareError { name, message }) => {
156                assert_eq!(name, "manipulator3000");
157                assert_eq!(message, "foo");
158            }
159            err => panic!("Unexpected error: {:?}", err),
160        }
161    }
162}