gear_sandbox_host/
error.rs

1// This file is part of Gear.
2
3// Copyright (C) Gear Technologies Inc.
4// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0
5
6// This program is free software: you can redistribute it and/or modify
7// it under the terms of the GNU General Public License as published by
8// the Free Software Foundation, either version 3 of the License, or
9// (at your option) any later version.
10
11// This program is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14// GNU General Public License for more details.
15
16// You should have received a copy of the GNU General Public License
17// along with this program. If not, see <https://www.gnu.org/licenses/>.
18
19//! Rust executor possible errors.
20
21/// Result type alias.
22pub type Result<T> = std::result::Result<T, Error>;
23
24/// Error type.
25#[derive(Debug, thiserror::Error)]
26#[allow(missing_docs)]
27pub enum Error {
28    #[error(transparent)]
29    Wasmi(#[from] wasmi::Error),
30
31    #[error("Sandbox error: {0}")]
32    Sandbox(String),
33
34    #[error("Error calling api function: {0}")]
35    ApiError(Box<dyn std::error::Error + Send + Sync>),
36
37    #[error("Method not found: '{0}'")]
38    MethodNotFound(String),
39
40    #[error("On-chain runtime does not specify version")]
41    VersionInvalid,
42
43    #[error("Externalities error")]
44    Externalities,
45
46    #[error("Invalid index provided")]
47    InvalidIndex,
48
49    #[error("Invalid type returned (should be u64)")]
50    InvalidReturn,
51
52    #[error("Runtime error")]
53    Runtime,
54
55    #[error("Runtime panicked: {0}")]
56    RuntimePanicked(String),
57
58    #[error("Invalid memory reference")]
59    InvalidMemoryReference,
60
61    #[error("The runtime doesn't provide a global named `__heap_base` of type `i32`")]
62    HeapBaseNotFoundOrInvalid,
63
64    #[error("The runtime must not have the `start` function defined")]
65    RuntimeHasStartFn,
66
67    #[error("Other: {0}")]
68    Other(String),
69
70    #[error(transparent)]
71    Allocator(#[from] sp_allocator::Error),
72
73    #[error("Host function {0} execution failed with: {1}")]
74    FunctionExecution(String, String),
75
76    #[error("No table exported by wasm blob")]
77    NoTable,
78
79    #[error("No table entry with index {0} in wasm blob exported table")]
80    NoTableEntryWithIndex(u32),
81
82    #[error("Table element with index {0} is not a function in wasm blob exported table")]
83    TableElementIsNotAFunction(u32),
84
85    #[error("Table entry with index {0} in wasm blob is null")]
86    FunctionRefIsNull(u32),
87
88    #[error(transparent)]
89    RuntimeConstruction(#[from] WasmError),
90
91    #[error("Shared memory is not supported")]
92    SharedMemUnsupported,
93
94    #[error("Imported globals are not supported yet")]
95    ImportedGlobalsUnsupported,
96
97    #[error("initializer expression can have only up to 2 expressions in wasm 1.0")]
98    InitializerHasTooManyExpressions,
99
100    #[error("Invalid initializer expression provided {0}")]
101    InvalidInitializerExpression(String),
102
103    #[error("Execution aborted due to panic: {0}")]
104    AbortedDueToPanic(MessageWithBacktrace),
105
106    #[error("Execution aborted due to trap: {0}")]
107    AbortedDueToTrap(MessageWithBacktrace),
108}
109
110impl wasmi::core::HostError for Error {}
111
112impl From<&'_ str> for Error {
113    fn from(err: &'_ str) -> Error {
114        Error::Other(err.into())
115    }
116}
117
118impl From<String> for Error {
119    fn from(err: String) -> Error {
120        Error::Other(err)
121    }
122}
123
124/// Type for errors occurring during Wasm runtime construction.
125#[derive(Debug, thiserror::Error)]
126#[allow(missing_docs)]
127pub enum WasmError {
128    #[error("Code could not be read from the state.")]
129    CodeNotFound,
130
131    #[error("Failure to reinitialize runtime instance from snapshot.")]
132    ApplySnapshotFailed,
133
134    /// Failure to erase the wasm memory.
135    ///
136    /// Depending on the implementation might mean failure of allocating memory.
137    #[error("Failure to erase the wasm memory: {0}")]
138    ErasingFailed(String),
139
140    #[error("Wasm code failed validation.")]
141    InvalidModule,
142
143    #[error("Wasm code could not be deserialized.")]
144    CantDeserializeWasm,
145
146    #[error("The module does not export a linear memory named `memory`.")]
147    InvalidMemory,
148
149    #[error("The number of heap pages requested is disallowed by the module.")]
150    InvalidHeapPages,
151
152    /// Instantiation error.
153    #[error("{0}")]
154    Instantiation(String),
155
156    /// Other error happened.
157    #[error("{0}")]
158    Other(String),
159}
160
161/// An error message with an attached backtrace.
162#[derive(Debug)]
163pub struct MessageWithBacktrace {
164    /// The error message.
165    pub message: String,
166
167    /// The backtrace associated with the error message.
168    pub backtrace: Option<Backtrace>,
169}
170
171impl std::fmt::Display for MessageWithBacktrace {
172    fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
173        fmt.write_str(&self.message)?;
174        if let Some(ref backtrace) = self.backtrace {
175            fmt.write_str("\nWASM backtrace:\n")?;
176            backtrace.backtrace_string.fmt(fmt)?;
177        }
178
179        Ok(())
180    }
181}
182
183/// A WASM backtrace.
184#[derive(Debug)]
185pub struct Backtrace {
186    /// The string containing the backtrace.
187    pub backtrace_string: String,
188}
189
190impl std::fmt::Display for Backtrace {
191    fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
192        fmt.write_str(&self.backtrace_string)
193    }
194}