opentelemetry_spanprocessor_any/global/
error_handler.rs1use 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 static ref GLOBAL_ERROR_HANDLER: RwLock<Option<ErrorHandler>> = RwLock::new(None);
12}
13
14#[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 Trace(#[from] TraceError),
23 #[cfg(feature = "metrics")]
24 #[cfg_attr(docsrs, doc(cfg(feature = "metrics")))]
25 #[error(transparent)]
26 Metric(#[from] MetricsError),
28 #[error("{0}")]
29 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
41pub 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
59pub 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}