ckb_sentry_error_chain/
lib.rs

1//! Adds support for the error-chain crate.
2//!
3//! Errors created by the `error-chain` crate can be logged with the
4//! `error_chain` integration.
5//!
6//! # Example
7//!
8//! ```no_run
9//! # #[macro_use] extern crate error_chain;
10//!
11//! use ckb_sentry_error_chain as sentry_error_chain;
12//!
13//! # error_chain! {}
14//! use sentry_error_chain::{capture_error_chain, ErrorChainIntegration};
15//! # fn function_that_might_fail() -> Result<()> { Ok(()) }
16//! # fn test() -> Result<()> {
17//! let _sentry =
18//!     sentry::init(sentry::ClientOptions::default().add_integration(ErrorChainIntegration));
19//! let result = match function_that_might_fail() {
20//!     Ok(result) => result,
21//!     Err(err) => {
22//!         capture_error_chain(&err);
23//!         return Err(err);
24//!     }
25//! };
26//! # Ok(()) }
27//! ```
28
29#![doc(html_favicon_url = "https://sentry-brand.storage.googleapis.com/favicon.ico")]
30#![doc(html_logo_url = "https://sentry-brand.storage.googleapis.com/sentry-glyph-black.png")]
31#![warn(missing_docs)]
32#![deny(unsafe_code)]
33#![allow(deprecated)]
34
35use std::fmt::{Debug, Display};
36
37use error_chain::ChainedError;
38use sentry_backtrace::backtrace_to_stacktrace;
39use sentry_core::parse_type_from_debug;
40use sentry_core::protocol::{Event, Exception, Level};
41use sentry_core::types::Uuid;
42use sentry_core::{ClientOptions, Hub, Integration};
43
44fn exceptions_from_error_chain<T>(error: &T) -> Vec<Exception>
45where
46    T: ChainedError,
47    T::ErrorKind: Debug + Display,
48{
49    let dbg = format!("{:?}", error.kind());
50    let mut rv = vec![];
51    rv.push(Exception {
52        ty: parse_type_from_debug(&dbg).to_owned(),
53        value: Some(error.kind().to_string()),
54        stacktrace: error_chain::ChainedError::backtrace(error).and_then(backtrace_to_stacktrace),
55        ..Default::default()
56    });
57
58    for error in error.iter().skip(1) {
59        let dbg = format!("{:?}", error);
60        rv.push(Exception {
61            ty: parse_type_from_debug(&dbg).to_owned(),
62            value: Some(error.to_string()),
63            ..Default::default()
64        })
65    }
66
67    rv
68}
69
70/// Creates an event from an error chain.
71#[deprecated = "The `error_chain` integration is deprecated and will be removed in the future."]
72pub fn event_from_error_chain<T>(e: &T) -> Event<'static>
73where
74    T: ChainedError,
75    T::ErrorKind: Debug + Display,
76{
77    Event {
78        exception: exceptions_from_error_chain(e).into(),
79        level: Level::Error,
80        ..Default::default()
81    }
82}
83
84/// Captures an error chain.
85#[deprecated = "The `error_chain` integration is deprecated and will be removed in the future."]
86pub fn capture_error_chain<T>(e: &T) -> Uuid
87where
88    T: ChainedError,
89    T::ErrorKind: Debug + Display,
90{
91    Hub::with_active(|hub| hub.capture_error_chain(e))
92}
93
94/// Hub extension methods for working with error chain
95#[deprecated = "The `error_chain` integration is deprecated and will be removed in the future."]
96pub trait ErrorChainHubExt {
97    /// Captures an error chain on a specific hub.
98    fn capture_error_chain<T>(&self, e: &T) -> Uuid
99    where
100        T: ChainedError,
101        T::ErrorKind: Debug + Display;
102}
103
104impl ErrorChainHubExt for Hub {
105    fn capture_error_chain<T>(&self, e: &T) -> Uuid
106    where
107        T: ChainedError,
108        T::ErrorKind: Debug + Display,
109    {
110        self.capture_event(event_from_error_chain(e))
111    }
112}
113
114/// The Sentry `error-chain` Integration.
115#[derive(Debug, Default)]
116#[deprecated = "The `error_chain` integration is deprecated and will be removed in the future."]
117pub struct ErrorChainIntegration;
118
119impl ErrorChainIntegration {
120    /// Creates a new `error-chain` Integration.
121    pub fn new() -> Self {
122        Self::default()
123    }
124}
125
126impl Integration for ErrorChainIntegration {
127    fn name(&self) -> &'static str {
128        "error-chain"
129    }
130
131    fn setup(&self, cfg: &mut ClientOptions) {
132        cfg.in_app_exclude.push("error_chain::");
133        cfg.extra_border_frames.push("error_chain::make_backtrace");
134    }
135}