frame_core/runtime/error.rs
1//! Typed refusals and failures from the composed component runtime.
2
3use thiserror::Error;
4
5use crate::composition::SchedulerCompositionError;
6
7/// A typed refusal or failure from [`crate::runtime::ComponentRuntime`] or
8/// [`crate::runtime::mailbox_integer`].
9#[derive(Debug, Error)]
10pub enum RuntimeError {
11 /// The policy asked for zero scheduler threads. beamr would silently
12 /// substitute the machine's parallelism; the wrapper refuses instead —
13 /// policy values are stated, never defaulted.
14 #[error("runtime policy declares zero scheduler threads; state a positive thread count")]
15 ZeroSchedulerThreads,
16 /// The policy asked for a zero operation timeout, which would make every
17 /// spawn, mailbox round-trip, and tombstone observation time out
18 /// immediately.
19 #[error("runtime policy declares a zero operation timeout; state a positive deadline")]
20 ZeroOperationTimeout,
21 /// Scheduler composition (BIF population + construction) failed.
22 #[error("scheduler composition failed")]
23 Composition {
24 /// Exact typed composition refusal.
25 #[source]
26 source: SchedulerCompositionError,
27 },
28 /// The runtime refused or failed to hot-load a support module.
29 #[error("support module load failed: {detail}")]
30 SupportModuleLoad {
31 /// Exact loader refusal.
32 detail: String,
33 },
34 /// A support module vanished from the committed table immediately after
35 /// its hot load reported success.
36 #[error("support module {module} was absent immediately after hot load")]
37 SupportModuleAbsent {
38 /// Module whose committed entry was missing.
39 module: String,
40 },
41 /// A freshly loaded support module's committed import table still defers
42 /// `erlang:*` entries — process-fatal at first dispatch, refused up
43 /// front (the same wall the registry applies to component bytecode).
44 #[error("support module {module} left erlang:* imports deferred: {imports}")]
45 SupportModuleDeferredBifImports {
46 /// Refused module.
47 module: String,
48 /// The deferred `erlang:name/arity` entries.
49 imports: String,
50 },
51 /// A retained old generation of a support module could not be safely
52 /// purged during unload.
53 #[error("failed to purge support module {module}: {detail}")]
54 SupportModulePurge {
55 /// Module whose old generation resisted the purge.
56 module: String,
57 /// Exact beamr purge refusal.
58 detail: String,
59 },
60 /// Deleting a support module's current generation failed — the module
61 /// was not loaded (a stale handle) or still had unpurged old code.
62 #[error("failed to delete support module {module} during unload")]
63 SupportModuleDelete {
64 /// Module the delete step refused.
65 module: String,
66 },
67 /// A support module was still committed after its verified unload — the
68 /// runtime never reports an unload it cannot prove.
69 #[error("support module {module} remained loaded after unload")]
70 SupportModuleStillLoaded {
71 /// Module still present after purge + delete.
72 module: String,
73 },
74 /// Final teardown was refused because the process tree still has residue;
75 /// every component must complete its ordered stop first.
76 #[error("shutdown refused: {count} live scheduler process(es) remain after ordered stop")]
77 ProcessResidue {
78 /// Processes still alive on the scheduler.
79 count: usize,
80 },
81 /// The reserved bound handed to [`crate::runtime::mailbox_integer`] lies
82 /// outside the mailbox integer domain, leaving no valid value to fold
83 /// into.
84 #[error(
85 "mailbox reserved bound {reserved_below} is outside the valid domain 0..={max}; \
86 no mailbox integer can be derived above it"
87 )]
88 MailboxReservedRangeInvalid {
89 /// The refused bound (every integer strictly below it is reserved).
90 reserved_below: i64,
91 /// The largest representable mailbox integer.
92 max: i64,
93 },
94}