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