1 //! Types for the public API around exceptions.
2 //!
3 //! To allow host code to interact with exceptions, Wasmtime provides
4 //! two basic areas of API:
5 //!
6 //! - The [`crate::ExnRef`] type and associated types allow the host
7 //!   to create exception objects. In the Wasm execution model, every
8 //!   thrown exception is a unique instance of an exception object,
9 //!   which carries a reference to the associated tag and any payload
10 //!   values specified by the exception's signature.
11 //!
12 //! - The [`crate::Store::throw`] method to throw an exception, and
13 //!   associated methods to take ([`crate::Store::take_exception`]) or
14 //!   peek at ([`crate::Store::peek_exception`]) a thrown exception,
15 //!   along with the `Error` type [`ThrownException`] that indicates
16 //!   an exception is being thrown. This API allows access to a
17 //!   "pending exception" slot on the `Store` which roots an exception
18 //!   object and allows it to be propagated through Wasm and hostcall
19 //!   layers. If Wasm code throws an uncaught exception, it will be
20 //!   set as the pending exception and the call into Wasm will return
21 //!   an `Err(ThrownException.into())`; if a hostcall wishes to throw
22 //!   an exception to be caught by Wasm (or the outer call into Wasm
23 //!   by the host), it can call `Store::throw` and return the
24 //!   associated error.
25 
26 /// An error type that represents that a pending WebAssembly exception
27 /// is set on the associated `Store`.
28 ///
29 /// When used as an error type and returned from a Wasm-to-host call,
30 /// or host-to-Wasm call, it indicates that the caller should either
31 /// continue propagating the error upward, or take and handle the
32 /// exception using [`Store::take_pending_exception`].
33 ///
34 /// [`Store::take_pending_exception`]: crate::Store::take_pending_exception
35 ///
36 /// Wasmtime uses an error type *without* payload, and stores the
37 /// exception itself on the store, to maintain proper GC rooting;
38 /// otherwise, it is difficult to get exception propagation up the
39 /// stack right in the presence of nested handle scopes. A pending
40 /// exception on the store is safely rooted as long as it is stored
41 /// there.
42 #[derive(Debug)]
43 pub struct ThrownException;
44 
45 /// We need to implement Error for `ThrownException` so it can be boxed up into
46 /// a `wasmtime::Error`.
47 impl core::error::Error for ThrownException {}
48 
49 /// `Error` requires `Display`.
50 impl core::fmt::Display for ThrownException {
fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result51     fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
52         write!(f, "thrown Wasm exception")
53     }
54 }
55