sc_observability_types/
errors.rs1use serde::{Deserialize, Serialize};
2use thiserror::Error;
3
4use crate::{Diagnostic, DiagnosticInfo, ErrorContext, sealed};
5
6#[derive(Debug, PartialEq, Serialize, Deserialize, Error)]
8#[error("{0}")]
9pub struct IdentityError(#[source] pub Box<ErrorContext>);
10
11impl sealed::Sealed for IdentityError {}
12
13impl DiagnosticInfo for IdentityError {
14 fn diagnostic(&self) -> &Diagnostic {
15 self.0.diagnostic()
16 }
17}
18
19macro_rules! error_wrapper {
20 ($(#[$meta:meta])* $name:ident) => {
21 $(#[$meta])*
22 #[derive(Debug, PartialEq, Serialize, Deserialize, Error)]
23 #[error("{0}")]
24 pub struct $name(#[source] pub Box<ErrorContext>);
25
26 impl sealed::Sealed for $name {}
27
28 impl DiagnosticInfo for $name {
29 fn diagnostic(&self) -> &Diagnostic {
30 self.0.diagnostic()
31 }
32 }
33 };
34}
35
36error_wrapper!(
37 InitError
39);
40error_wrapper!(
41 EventError
43);
44error_wrapper!(
45 FlushError
47);
48error_wrapper!(
49 ShutdownError
51);
52error_wrapper!(
53 ProjectionError
55);
56error_wrapper!(
57 SubscriberError
59);
60error_wrapper!(
61 LogSinkError
63);
64error_wrapper!(
65 ExportError
67);
68
69#[derive(Debug, PartialEq, Serialize, Deserialize, Error)]
71pub enum ObservationError {
72 #[error("observation runtime is shut down")]
73 Shutdown,
75 #[error("{0}")]
76 QueueFull(#[source] Box<ErrorContext>),
78 #[error("{0}")]
79 RoutingFailure(#[source] Box<ErrorContext>),
81}
82
83#[derive(Debug, PartialEq, Serialize, Deserialize, Error)]
85pub enum TelemetryError {
86 #[error("telemetry runtime is shut down")]
87 Shutdown,
89 #[error("{0}")]
90 ExportFailure(#[source] Box<ErrorContext>),
92}
93
94#[cfg(test)]
95mod tests {
96 use super::*;
97 use crate::{Remediation, error_codes};
98
99 #[test]
100 fn wrapper_errors_expose_source_context() {
101 let wrapped = InitError(Box::new(
102 ErrorContext::new(
103 error_codes::DIAGNOSTIC_INVALID,
104 "operation failed",
105 Remediation::not_recoverable("investigate manually"),
106 )
107 .source(Box::new(std::io::Error::other("disk full"))),
108 ));
109
110 let source = std::error::Error::source(&wrapped).expect("context source");
111 assert_eq!(source.to_string(), "operation failed; caused by: disk full");
112 assert_eq!(
113 source.source().map(ToString::to_string).as_deref(),
114 Some("disk full")
115 );
116 }
117}