near_vm_compiler/
error.rs

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