Skip to main content

lightshuttle_runtime/lifecycle/
error.rs

1//! Error types returned by [`crate::LifecycleManager`] and [`crate::LifecyclePlan`].
2//!
3//! [`LifecycleError`] is the top-level error type for the lifecycle layer. It
4//! wraps lower-level [`crate::RuntimeError`] values (from the container
5//! runtime) and [`lightshuttle_spec::SpecError`] values (from manifest
6//! conversion), and adds lifecycle-specific variants such as dependency cycles,
7//! healthcheck timeouts, and missing environment variables.
8
9use std::time::Duration;
10
11use lightshuttle_spec::SpecError;
12
13use crate::error::RuntimeError;
14
15/// Errors raised by the lifecycle layer.
16#[derive(Debug, thiserror::Error)]
17pub enum LifecycleError {
18    /// The dependency graph contains a cycle.
19    #[error("cycle detected in dependency graph: {0}")]
20    Cycle(String),
21
22    /// Converting a manifest resource into a [`crate::ContainerSpec`] failed.
23    #[error("manifest conversion failed for `{resource}`")]
24    SpecBuild {
25        /// Resource whose conversion failed.
26        resource: String,
27        /// Underlying specification error.
28        #[source]
29        source: SpecError,
30    },
31
32    /// A resource failed to start.
33    #[error("failed to start resource `{resource}`")]
34    Start {
35        /// Resource that failed.
36        resource: String,
37        /// Underlying runtime error.
38        #[source]
39        source: RuntimeError,
40    },
41
42    /// A resource failed to stop cleanly.
43    #[error("failed to stop resource `{resource}`")]
44    Stop {
45        /// Resource that failed.
46        resource: String,
47        /// Underlying runtime error.
48        #[source]
49        source: RuntimeError,
50    },
51
52    /// A resource never became healthy within the configured timeout.
53    #[error("resource `{resource}` healthcheck timed out after {timeout:?}")]
54    HealthcheckTimeout {
55        /// Resource that did not become healthy.
56        resource: String,
57        /// Configured timeout.
58        timeout: Duration,
59    },
60
61    /// A dependency of the resource failed.
62    #[error("dependency `{dependency}` for `{resource}` failed: {reason}")]
63    DependencyFailed {
64        /// Resource whose start was blocked.
65        resource: String,
66        /// Dependency that failed.
67        dependency: String,
68        /// Reason reported by the failed dependency.
69        reason: String,
70    },
71
72    /// A reference targets a resource that does not exist in the plan.
73    #[error("resource `{0}` not found in the current plan")]
74    ResourceNotFound(String),
75
76    /// One or more `${env.VAR}` references in the manifest cannot be
77    /// resolved because the variables are unset and have no default.
78    #[error(
79        "missing required environment variable(s): {}",
80        names.join(", ")
81    )]
82    MissingEnvVars {
83        /// Sorted, deduplicated list of missing variable names.
84        names: Vec<String>,
85    },
86}