lucet_runtime_internals/
error.rs

1use crate::instance::{FaultDetails, TerminationDetails};
2use thiserror::Error;
3
4/// Lucet runtime errors.
5#[derive(Debug, Error)]
6pub enum Error {
7    #[error("Invalid argument: {0}")]
8    InvalidArgument(&'static str),
9
10    /// A [`Region`](trait.Region.html) cannot currently accommodate additional instances.
11    #[error("Region capacity reached: {0} instances")]
12    RegionFull(usize),
13
14    /// A module error occurred.
15    #[error("Module error: {0}")]
16    ModuleError(ModuleError),
17
18    /// A method call or module specification would exceed an instance's
19    /// [`Limit`s](struct.Limits.html).
20    #[error("Instance limits exceeded: {0}")]
21    LimitsExceeded(String),
22
23    /// A method call attempted to modify linear memory for an instance that
24    /// does not have linear memory
25    #[error("No linear memory available: {0}")]
26    NoLinearMemory(String),
27
28    /// An attempt to look up a WebAssembly function by its symbol name failed.
29    #[error("Symbol not found: {0}")]
30    SymbolNotFound(String),
31
32    /// An attempt to look up a WebAssembly function by its table index failed.
33    #[error("Function not found: (table {0}, func {1}")]
34    FuncNotFound(u32, u32),
35
36    /// An instance aborted due to a runtime fault.
37    #[error("Runtime fault: {0:?}")]
38    RuntimeFault(FaultDetails),
39
40    /// An instance terminated, potentially with extra information about the termination.
41    ///
42    /// This condition can arise from a hostcall explicitly calling
43    /// [`Vmctx::terminate()`](vmctx/struct.Vmctx.html#method.terminate), or via a custom signal handler
44    /// that returns [`SignalBehavior::Terminate`](enum.SignalBehavior.html#variant.Terminate).
45    #[error("Runtime terminated")]
46    RuntimeTerminated(TerminationDetails),
47
48    /// IO errors arising during dynamic loading with [`DlModule`](struct.DlModule.html).
49    #[error("Dynamic loading error: {0}")]
50    DlError(#[from] std::io::Error),
51
52    #[error("Instance not returned")]
53    InstanceNotReturned,
54
55    #[error("Instance not yielded")]
56    InstanceNotYielded,
57
58    #[error("Start function yielded")]
59    StartYielded,
60
61    /// A catch-all for internal errors that are likely unrecoverable by the runtime user.
62    ///
63    /// As the API matures, these will likely become rarer, replaced by new variants of this enum,
64    /// or by panics for truly unrecoverable situations.
65    #[error("Internal error")]
66    InternalError(#[source] anyhow::Error),
67
68    /// An unsupported feature was used.
69    #[error("Unsupported feature: {0}")]
70    Unsupported(String),
71}
72
73impl From<crate::context::Error> for Error {
74    fn from(e: crate::context::Error) -> Error {
75        Error::InternalError(e.into())
76    }
77}
78
79impl From<nix::Error> for Error {
80    fn from(e: nix::Error) -> Error {
81        Error::InternalError(e.into())
82    }
83}
84
85impl From<std::ffi::IntoStringError> for Error {
86    fn from(e: std::ffi::IntoStringError) -> Error {
87        Error::InternalError(e.into())
88    }
89}
90
91impl From<lucet_module::Error> for Error {
92    fn from(e: lucet_module::Error) -> Error {
93        Error::ModuleError(ModuleError::ModuleDataError(e))
94    }
95}
96
97/// Lucet module errors.
98#[derive(Debug, Error)]
99pub enum ModuleError {
100    /// An error was found in the definition of a Lucet module.
101    #[error("Incorrect module definition: {0}")]
102    IncorrectModule(String),
103
104    /// An error occurred with the module data section, likely during deserialization.
105    #[error("Module data error: {0}")]
106    ModuleDataError(#[from] lucet_module::Error),
107}
108
109#[macro_export]
110macro_rules! lucet_bail {
111    ($e:expr) => {
112        return Err(lucet_format_err!($e));
113    };
114    ($fmt:expr, $($arg:tt)*) => {
115        return Err(lucet_format_err!($fmt, $($arg)*));
116    };
117}
118
119#[macro_export(local_inner_macros)]
120macro_rules! lucet_ensure {
121    ($cond:expr, $e:expr) => {
122        if !($cond) {
123            lucet_bail!($e);
124        }
125    };
126    ($cond:expr, $fmt:expr, $($arg:tt)*) => {
127        if !($cond) {
128            lucet_bail!($fmt, $($arg)*);
129        }
130    };
131}
132
133#[macro_export]
134macro_rules! lucet_format_err {
135    ($($arg:tt)*) => { $crate::error::Error::InternalError(anyhow::format_err!($($arg)*)) }
136}
137
138#[macro_export]
139macro_rules! lucet_incorrect_module {
140    ($($arg:tt)*) => {
141        $crate::error::Error::ModuleError(
142            $crate::error::ModuleError::IncorrectModule(format!($($arg)*))
143        )
144    }
145}
146
147#[macro_export]
148macro_rules! bail_limits_exceeded {
149    ($($arg:tt)*) => { return Err($crate::error::Error::LimitsExceeded(format!($($arg)*))); }
150}