Skip to main content

gsc_executor_common/
error.rs

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