xref: /wasmtime-44.0.1/crates/wasi/src/error.rs (revision d73bd632)
1 use std::error::Error;
2 use std::fmt;
3 use std::marker;
4 
5 /// An error returned from the `proc_exit` host syscall.
6 ///
7 /// Embedders can test if an error returned from wasm is this error, in which
8 /// case it may signal a non-fatal trap.
9 #[derive(Debug)]
10 pub struct I32Exit(pub i32);
11 
12 impl fmt::Display for I32Exit {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result13     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
14         write!(f, "Exited with i32 exit status {}", self.0)
15     }
16 }
17 
18 impl std::error::Error for I32Exit {}
19 
20 /// A helper error type used by many other modules through type aliases.
21 ///
22 /// This type is an `Error` itself and is intended to be a representation of
23 /// either:
24 ///
25 /// * A custom error type `T`
26 /// * A trap, represented as `wasmtime::Error`
27 ///
28 /// This error is created through either the `::trap` constructor representing a
29 /// full-fledged trap or the `From<T>` constructor which is intended to be used
30 /// with `?`. The goal is to make normal errors `T` "automatic" but enable error
31 /// paths to return a `::trap` error optionally still as necessary without extra
32 /// boilerplate everywhere else.
33 ///
34 /// Note that this type isn't used directly but instead is intended to be used
35 /// as:
36 ///
37 /// ```rust,ignore
38 /// type MyError = TrappableError<bindgen::TheError>;
39 /// ```
40 ///
41 /// where `MyError` is what you'll use throughout bindings code and
42 /// `bindgen::TheError` is the type that this represents as generated by the
43 /// `bindgen!` macro.
44 #[repr(transparent)]
45 pub struct TrappableError<T> {
46     err: wasmtime::Error,
47     _marker: marker::PhantomData<T>,
48 }
49 
50 impl<T> TrappableError<T> {
trap(err: impl Into<wasmtime::Error>) -> TrappableError<T>51     pub fn trap(err: impl Into<wasmtime::Error>) -> TrappableError<T> {
52         TrappableError {
53             err: err.into(),
54             _marker: marker::PhantomData,
55         }
56     }
57 
downcast(self) -> wasmtime::Result<T> where T: Error + Send + Sync + 'static,58     pub fn downcast(self) -> wasmtime::Result<T>
59     where
60         T: Error + Send + Sync + 'static,
61     {
62         self.err.downcast()
63     }
64 
downcast_ref(&self) -> Option<&T> where T: Error + Send + Sync + 'static,65     pub fn downcast_ref(&self) -> Option<&T>
66     where
67         T: Error + Send + Sync + 'static,
68     {
69         self.err.downcast_ref()
70     }
71 }
72 
73 impl<T> From<T> for TrappableError<T>
74 where
75     T: Error + Send + Sync + 'static,
76 {
from(error: T) -> Self77     fn from(error: T) -> Self {
78         Self {
79             err: error.into(),
80             _marker: marker::PhantomData,
81         }
82     }
83 }
84 
85 impl<T> fmt::Debug for TrappableError<T> {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result86     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
87         self.err.fmt(f)
88     }
89 }
90 
91 impl<T> fmt::Display for TrappableError<T> {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result92     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
93         self.err.fmt(f)
94     }
95 }
96 
97 impl<T> Error for TrappableError<T> {}
98