wasmtime/runtime/
exception.rs

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 [`crate::Store::take_exception`] (or a helper such
33/// as [`crate::Store::catch`].
34///
35/// Wasmtime uses an error type *without* payload, and stores the
36/// exception itself on the store, to maintain proper GC rooting;
37/// otherwise, it is difficult to get exception propagation up the
38/// stack right in the presence of nested handle scopes. A pending
39/// exception on the store is safely rooted as long as it is stored
40/// there.
41#[derive(Debug)]
42pub struct ThrownException;
43
44/// We need to implement Error for `ThrownException` so it can be boxed up into an `anyhow::Error`.
45impl core::error::Error for ThrownException {}
46
47/// `Error` requires `Display`.
48impl core::fmt::Display for ThrownException {
49    fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
50        write!(f, "thrown Wasm exception")
51    }
52}