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}