Skip to main content

dig_service/
error.rs

1//! Service-level error types.
2//!
3//! Every fallible `Service` operation returns [`Result<T>`]
4//! = `Result<T, ServiceError>`. Errors are `Clone` (wrapping `anyhow::Error`
5//! in `Arc`) so they can fan out through broadcast channels or be bubbled
6//! through async traits without forcing the caller to stop.
7
8use std::sync::Arc;
9use std::time::Duration;
10
11use thiserror::Error;
12
13/// Convenience alias: `Result<T, ServiceError>`.
14pub type Result<T> = std::result::Result<T, ServiceError>;
15
16/// All failure modes of a running `Service`.
17#[derive(Error, Debug, Clone)]
18pub enum ServiceError {
19    /// The node's `pre_start` hook returned an error.
20    ///
21    /// No other lifecycle hooks are invoked after this — typical causes
22    /// are store open failures or journal replay errors.
23    #[error("pre_start failed: {0}")]
24    PreStartFailed(#[source] Arc<anyhow::Error>),
25
26    /// The node's `on_start` hook returned an error.
27    ///
28    /// `post_stop` is still invoked so resources opened in `pre_start`
29    /// have a chance to close.
30    #[error("on_start failed: {0}")]
31    OnStartFailed(#[source] Arc<anyhow::Error>),
32
33    /// The node's `run` hook returned an error.
34    ///
35    /// `on_stop` + `post_stop` are still invoked. The exit status's
36    /// `reason` is `ExitReason::RunError`.
37    #[error("run exited with error: {0}")]
38    RunFailed(#[source] Arc<anyhow::Error>),
39
40    /// The node's `on_stop` OR `post_stop` hook returned an error.
41    ///
42    /// Reported after `run` has returned; usually indicates a flush /
43    /// close failure.
44    #[error("on_stop failed: {0}")]
45    OnStopFailed(#[source] Arc<anyhow::Error>),
46
47    /// One or more tracked tasks did not exit within the shutdown deadline.
48    ///
49    /// The service aborts the laggards; this error is reported so operators
50    /// can see that shutdown was not fully graceful.
51    #[error("task registry deadline exceeded ({deadline:?}); {pending} tasks aborted")]
52    ShutdownDeadlineExceeded {
53        /// The deadline that was exceeded.
54        deadline: Duration,
55        /// How many tasks were still alive when the deadline fired.
56        pending: usize,
57    },
58
59    /// `start()` was called on a Service that has already run.
60    ///
61    /// A `Service` is single-shot — once started, build a new one.
62    #[error("service is already running")]
63    AlreadyRunning,
64
65    /// `start()` was called on a Service that has already stopped.
66    ///
67    /// Reserved for future re-entry protections; currently unreachable.
68    #[error("service has already stopped")]
69    AlreadyStopped,
70}