Skip to main content

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}