1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
// SPDX-License-Identifier: Apache-2.0
/// Errors created by this library
#[derive(Debug, thiserror::Error)]
#[non_exhaustive]
pub enum Error {
/// Api error
#[error(transparent)]
Api(#[from] ApiError),
/// Vm error
#[error(transparent)]
Vm(#[from] VmError),
/// Wasmtime runtime error
#[error("Wasmtime error: {message}")]
Wasmtime {
/// Error message (may include source error details)
message: String,
},
/// UTF-8 conversion error
#[error(transparent)]
Utf8(#[from] std::string::FromUtf8Error),
/// Custom error message with context
#[error("{message}")]
Custom {
/// Error message
message: String,
},
}
impl Error {
/// Creates a custom error from a string with backtrace
pub fn custom(s: &impl ToString) -> Self {
Self::Custom {
message: s.to_string(),
}
}
/// Creates a Wasmtime error with backtrace
pub fn wasmtime(message: impl Into<String>) -> Self {
Self::Wasmtime {
message: message.into(),
}
}
/// Creates a Wasmtime error from a `wasmtime::Error` with backtrace
#[must_use]
pub fn from_wasmtime(error: wasmtime::Error) -> Self {
Self::Wasmtime {
message: error.to_string(),
}
}
/// Adds context to the error
pub fn context(self, ctx: impl Into<String>) -> Self {
match self {
Self::Custom { message } => Self::Custom {
message: format!("{}: {}", ctx.into(), message),
},
other => other,
}
}
}
/// Api errors created by this library
#[derive(Debug, thiserror::Error)]
#[non_exhaustive]
pub enum ApiError {
/// Missing export from WASM module
#[error("missing vm export '{export_name}': {context}")]
MissingExport {
/// Name of the missing export
export_name: String,
/// Additional context
context: String,
},
/// Invalid function parameter
#[error("invalid vm function parameter at index {param_index}: {reason}")]
InvalidParam {
/// Parameter index that was invalid
param_index: usize,
/// Reason for invalidity
reason: String,
},
/// Incorrect number of parameters
#[error("incorrect number of vm function params; expected {expected}, received {received}")]
IncorrectNumberOfParams {
/// Expected number of parameters
expected: usize,
/// Received number of parameters
received: usize,
},
/// Incorrect number of results
#[error("incorrect number of vm function results; expected {expected}, received {received}")]
IncorrectNumberOfResults {
/// Expected number of results
expected: usize,
/// Received number of results
received: usize,
},
/// Failed to decode memory value
#[error("failed to get memory value at offset {offset}, length {length}: {reason}")]
MemoryDecodeError {
/// Memory offset
offset: usize,
/// Length to read
length: usize,
/// Reason for failure
reason: String,
},
/// Failed to register API function
#[error("failed to register API function '{function_name}': {reason}")]
RegisterApiFailed {
/// Function name
function_name: String,
/// Reason for failure
reason: String,
},
/// Missing key-value pair
#[error("no value associated with key '{key}' in {store}")]
NoValue {
/// The key that was not found
key: String,
/// Which store (current/proposed)
store: String,
},
/// Memory access error
#[error("memory access error at offset {offset}: {reason}")]
MemoryAccess {
/// Memory offset
offset: usize,
/// Reason for error
reason: String,
},
}
/// Vm errors created by this library
#[derive(Debug, thiserror::Error)]
#[non_exhaustive]
pub enum VmError {
/// Missing VM context during operation
#[error("missing VM context: {context}")]
MissingContext {
/// Context about where the error occurred
context: String,
},
/// Invalid key-path for the key-value store
#[error("invalid key-path '{path}': {reason}")]
InvalidKeyPath {
/// The invalid key-path
path: String,
/// Reason why it's invalid
reason: String,
},
/// Compilation error
#[error("compilation error: {message}")]
CompilationError {
/// Error message (includes source error details)
message: String,
},
/// Instantiation error
#[error("instantiation error: {message}")]
InstantiationError {
/// Error message (includes source error details)
message: String,
},
/// Execution error
#[error("execution error in function '{function}': {message}")]
ExecutionError {
/// Function name
function: String,
/// Error message (includes source error details)
message: String,
},
}