codewhale_workflow_js/error.rs
1//! Error types for the dynamic Workflow runtime.
2
3use thiserror::Error;
4
5/// Errors surfaced by [`crate::WorkflowVm::run_script`].
6///
7/// Script-visible failures (thrown JS exceptions, rejected promises, host
8/// function errors that were not caught inside the script) all collapse into
9/// [`WorkflowJsError::Script`] with the exception message and stack. The
10/// remaining variants describe runtime-level failures that never reached the
11/// script.
12#[derive(Debug, Error)]
13pub enum WorkflowJsError {
14 /// The QuickJS runtime or context could not be created.
15 #[error("failed to initialize the Workflow JS VM: {0}")]
16 VmInit(String),
17 /// The script threw (or a promise rejected) and nothing caught it.
18 /// Carries the exception message plus stack when available.
19 #[error("script error: {0}")]
20 Script(String),
21 /// The run was cancelled — either the caller dropped the run future or
22 /// the cooperative cancel signal fired mid-script.
23 #[error("workflow run cancelled")]
24 Cancelled,
25 /// The script completed but its return value could not be encoded as
26 /// JSON (e.g. it returned a function or a cyclic object).
27 #[error("script result is not JSON-encodable: {0}")]
28 ResultEncoding(String),
29 /// The invocation arguments could not be injected into the VM.
30 #[error("invalid workflow arguments: {0}")]
31 InvalidArgs(String),
32 /// The dedicated VM thread exited without reporting a result (panic or
33 /// spawn failure). Outstanding driver tasks are cancelled when this is
34 /// observed.
35 #[error("Workflow VM thread terminated unexpectedly: {0}")]
36 VmTerminated(String),
37}
38
39/// Errors a [`crate::WorkflowDriver`] can return from `spawn_task`.
40///
41/// Both variants surface inside the script as a thrown exception on the
42/// corresponding `task()` call, so a script can `try`/`catch` an individual
43/// rejection (admission, depth, budget) without the whole run failing.
44#[derive(Debug, Clone, Error)]
45pub enum DriverError {
46 /// The driver refused to spawn this task (admission cap, depth ceiling,
47 /// budget reservation failure, invalid subagent type, ...).
48 #[error("spawn rejected: {0}")]
49 Rejected(String),
50 /// The driver is gone or its channel closed; no more spawns will work.
51 #[error("driver unavailable: {0}")]
52 Unavailable(String),
53}