Skip to main content

telemetry_init/
error.rs

1//! Errors produced by telemetry initialization and shutdown.
2
3use thiserror::Error;
4
5/// Initialization and shutdown failures.
6///
7/// Documented failure modes are part of the API contract; every variant
8/// lists the condition that produces it.
9#[derive(Debug, Clone, PartialEq, Eq, Error)]
10#[non_exhaustive]
11pub enum TelemetryError {
12    /// A configuration or construction step failed before (or after) the
13    /// subscriber could be installed. The payload carries the underlying
14    /// message — an invalid `env-filter` directive, an unbuildable OTLP
15    /// exporter, or a failed shutdown flush.
16    #[error("telemetry init failed: {0}")]
17    InitFailed(String),
18    /// The global tracing subscriber is a once-per-process resource:
19    /// [`tracing::subscriber::set_global_default`] was already called by
20    /// this crate, another crate, or an earlier `Telemetry::init`. A
21    /// second bootstrap returns this error instead of panicking.
22    #[error("telemetry already initialized: the global subscriber is installed once per process")]
23    AlreadyInitialized,
24}
25
26#[cfg(test)]
27mod tests {
28    use super::*;
29
30    #[test]
31    fn display_is_informative() {
32        let e = TelemetryError::InitFailed("invalid directive".into());
33        assert_eq!(e.to_string(), "telemetry init failed: invalid directive");
34        assert_eq!(
35            TelemetryError::AlreadyInitialized.to_string(),
36            "telemetry already initialized: the global subscriber is installed once per process"
37        );
38    }
39
40    #[test]
41    fn is_std_error_with_source_none() {
42        let e = TelemetryError::InitFailed("boom".into());
43        let std_err: &dyn std::error::Error = &e;
44        assert!(std_err.to_string().contains("boom"));
45        assert!(std_err.source().is_none());
46    }
47
48    #[test]
49    fn debug_and_clone_round_trip() {
50        let e = TelemetryError::InitFailed("a".into());
51        let cloned = e.clone();
52        assert_eq!(format!("{e:?}"), r#"InitFailed("a")"#);
53        assert_eq!(e, cloned);
54        assert_ne!(e, TelemetryError::AlreadyInitialized);
55    }
56}