opentelemetry_spanprocessor_any/global/
error_handler.rs

1use std::sync::PoisonError;
2use std::sync::RwLock;
3
4#[cfg(feature = "metrics")]
5use crate::metrics::MetricsError;
6#[cfg(feature = "trace")]
7use crate::trace::TraceError;
8
9lazy_static::lazy_static! {
10    /// The global error handler.
11    static ref GLOBAL_ERROR_HANDLER: RwLock<Option<ErrorHandler>> = RwLock::new(None);
12}
13
14/// Wrapper for error from both tracing and metrics part of open telemetry.
15#[derive(thiserror::Error, Debug)]
16#[non_exhaustive]
17pub enum Error {
18    #[cfg(feature = "trace")]
19    #[cfg_attr(docsrs, doc(cfg(feature = "trace")))]
20    #[error(transparent)]
21    /// Failed to export traces.
22    Trace(#[from] TraceError),
23    #[cfg(feature = "metrics")]
24    #[cfg_attr(docsrs, doc(cfg(feature = "metrics")))]
25    #[error(transparent)]
26    /// An issue raised by the metrics module.
27    Metric(#[from] MetricsError),
28    #[error("{0}")]
29    /// Other types of failures not covered by the variants above.
30    Other(String),
31}
32
33impl<T> From<PoisonError<T>> for Error {
34    fn from(err: PoisonError<T>) -> Self {
35        Error::Other(err.to_string())
36    }
37}
38
39struct ErrorHandler(Box<dyn Fn(Error) + Send + Sync>);
40
41/// Handle error using the globally configured error handler.
42///
43/// Writes to stderr if unset.
44pub fn handle_error<T: Into<Error>>(err: T) {
45    match GLOBAL_ERROR_HANDLER.read() {
46        Ok(handler) if handler.is_some() => (handler.as_ref().unwrap().0)(err.into()),
47        _ => match err.into() {
48            #[cfg(feature = "metrics")]
49            #[cfg_attr(docsrs, doc(cfg(feature = "metrics")))]
50            Error::Metric(err) => eprintln!("OpenTelemetry metrics error occurred. {}", err),
51            #[cfg(feature = "trace")]
52            #[cfg_attr(docsrs, doc(cfg(feature = "trace")))]
53            Error::Trace(err) => eprintln!("OpenTelemetry trace error occurred. {}", err),
54            Error::Other(err_msg) => eprintln!("OpenTelemetry error occurred. {}", err_msg),
55        },
56    }
57}
58
59/// Set global error handler.
60pub fn set_error_handler<F>(f: F) -> std::result::Result<(), Error>
61where
62    F: Fn(Error) + Send + Sync + 'static,
63{
64    GLOBAL_ERROR_HANDLER
65        .write()
66        .map(|mut handler| *handler = Some(ErrorHandler(Box::new(f))))
67        .map_err(Into::into)
68}