Skip to main content

opentelemetry_sdk/
error.rs

1//! Wrapper for error from trace, logs and metrics part of open telemetry.
2
3use std::{fmt, result::Result, time::Duration};
4
5/// Trait for errors returned by exporters
6pub trait ExportError: std::error::Error + Send + Sync + 'static {
7    /// The name of exporter that returned this error
8    fn exporter_name(&self) -> &'static str;
9}
10
11#[derive(Debug)]
12/// Errors that can occur during SDK operations export(), force_flush() and shutdown().
13pub enum OTelSdkError {
14    /// Shutdown has already been invoked.
15    ///
16    /// While shutdown is idempotent and calling it multiple times has no
17    /// impact, this error suggests that another part of the application is
18    /// invoking `shutdown` earlier than intended. Users should review their
19    /// code to identify unintended or duplicate shutdown calls and ensure it is
20    /// only triggered once at the correct place.
21    AlreadyShutdown,
22
23    /// Operation timed out before completing.
24    ///
25    /// This does not necessarily indicate a failure—operation may still be
26    /// complete. If this occurs frequently, consider increasing the timeout
27    /// duration to allow more time for completion.
28    Timeout(Duration),
29
30    /// Operation failed due to an internal error.
31    ///
32    /// The error message is intended for logging purposes only and should not
33    /// be used to make programmatic decisions. It is implementation-specific
34    /// and subject to change without notice. Consumers of this error should not
35    /// rely on its content beyond logging.
36    InternalFailure(String),
37}
38
39impl fmt::Display for OTelSdkError {
40    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
41        match self {
42            OTelSdkError::AlreadyShutdown => write!(f, "Shutdown already invoked"),
43            OTelSdkError::Timeout(duration) => {
44                write!(f, "Operation timed out after {duration:?}")
45            }
46            OTelSdkError::InternalFailure(reason) => write!(f, "Operation failed: {reason}"),
47        }
48    }
49}
50
51impl std::error::Error for OTelSdkError {}
52
53#[cfg(any(feature = "testing", test))]
54impl<T> From<std::sync::PoisonError<T>> for OTelSdkError {
55    fn from(err: std::sync::PoisonError<T>) -> Self {
56        OTelSdkError::InternalFailure(format!("Mutex poison error: {err}"))
57    }
58}
59
60/// A specialized `Result` type for Shutdown operations.
61pub type OTelSdkResult = Result<(), OTelSdkError>;
62
63#[cfg(test)]
64mod tests {
65    use super::*;
66
67    #[test]
68    fn display_matches_variants() {
69        assert_eq!(
70            OTelSdkError::AlreadyShutdown.to_string(),
71            "Shutdown already invoked"
72        );
73        assert_eq!(
74            OTelSdkError::Timeout(Duration::from_secs(5)).to_string(),
75            "Operation timed out after 5s"
76        );
77        assert_eq!(
78            OTelSdkError::InternalFailure("db unreachable".into()).to_string(),
79            "Operation failed: db unreachable"
80        );
81    }
82}