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}