1#![doc(html_favicon_url = "https://sentry-brand.storage.googleapis.com/favicon.ico")]
28#![doc(html_logo_url = "https://sentry-brand.storage.googleapis.com/sentry-glyph-black.png")]
29#![warn(missing_docs)]
30#![deny(unsafe_code)]
31#![warn(missing_doc_code_examples)]
32#![allow(deprecated)]
33
34use std::panic::PanicInfo;
35
36use failure::{Error, Fail};
37use sentry_backtrace::parse_stacktrace;
38use sentry_core::parse_type_from_debug;
39use sentry_core::protocol::{Event, Exception, Level};
40use sentry_core::types::Uuid;
41use sentry_core::{ClientOptions, Hub, Integration};
42
43#[derive(Debug, Default)]
45#[deprecated = "The `failure` integration is deprecated and will be removed in the future."]
46pub struct FailureIntegration;
47
48impl FailureIntegration {
49 pub fn new() -> Self {
51 Self::default()
52 }
53}
54
55impl Integration for FailureIntegration {
56 fn name(&self) -> &'static str {
57 "failure"
58 }
59
60 fn setup(&self, cfg: &mut ClientOptions) {
61 cfg.in_app_exclude.push("failure::");
62 cfg.extra_border_frames.extend_from_slice(&[
63 "failure::error_message::err_msg",
64 "failure::backtrace::Backtrace::new",
65 "failure::backtrace::internal::InternalBacktrace::new",
66 "failure::Fail::context",
67 ]);
68 }
69}
70
71#[deprecated = "The `failure` integration is deprecated and will be removed in the future."]
84pub fn panic_extractor(info: &PanicInfo<'_>) -> Option<Event<'static>> {
85 let error = info.payload().downcast_ref::<Error>()?;
86 Some(Event {
87 level: Level::Fatal,
88 ..event_from_error(error)
89 })
90}
91
92#[deprecated = "The `failure` integration is deprecated and will be removed in the future."]
100pub fn exception_from_single_fail<F: Fail + ?Sized>(
101 f: &F,
102 bt: Option<&failure::Backtrace>,
103) -> Exception {
104 let dbg = format!("{:?}", f);
105 Exception {
106 ty: parse_type_from_debug(&dbg).to_owned(),
107 value: Some(f.to_string()),
108 stacktrace: bt
109 .map(|bt| format!("{:#?}", bt))
111 .and_then(|x| parse_stacktrace(&x)),
112 ..Default::default()
113 }
114}
115
116#[deprecated = "The `failure` integration is deprecated and will be removed in the future."]
118pub fn event_from_error(err: &failure::Error) -> Event<'static> {
119 let mut exceptions: Vec<_> = err
120 .iter_chain()
121 .enumerate()
122 .map(|(idx, cause)| {
123 let bt = match cause.backtrace() {
124 Some(bt) => Some(bt),
125 None if idx == 0 => Some(err.backtrace()),
126 None => None,
127 };
128 exception_from_single_fail(cause, bt)
129 })
130 .collect();
131 exceptions.reverse();
132
133 Event {
134 exception: exceptions.into(),
135 level: Level::Error,
136 ..Default::default()
137 }
138}
139
140#[deprecated = "The `failure` integration is deprecated and will be removed in the future."]
142pub fn event_from_fail<F: Fail + ?Sized>(fail: &F) -> Event<'static> {
143 let mut exceptions = vec![exception_from_single_fail(fail, fail.backtrace())];
144
145 let mut ptr: Option<&dyn Fail> = None;
146 while let Some(cause) = ptr.map(Fail::cause).unwrap_or_else(|| fail.cause()) {
147 exceptions.push(exception_from_single_fail(cause, cause.backtrace()));
148 ptr = Some(cause);
149 }
150
151 exceptions.reverse();
152 Event {
153 exception: exceptions.into(),
154 level: Level::Error,
155 ..Default::default()
156 }
157}
158
159#[deprecated = "The `failure` integration is deprecated and will be removed in the future."]
163pub fn capture_error(err: &Error) -> Uuid {
164 Hub::with_active(|hub| FailureHubExt::capture_error(hub.as_ref(), err))
165}
166
167#[deprecated = "The `failure` integration is deprecated and will be removed in the future."]
171pub fn capture_fail<F: Fail + ?Sized>(fail: &F) -> Uuid {
172 Hub::with_active(|hub| hub.capture_fail(fail))
173}
174
175#[deprecated = "The `failure` integration is deprecated and will be removed in the future."]
177pub trait FailureHubExt {
178 fn capture_error(&self, err: &Error) -> Uuid;
180 fn capture_fail<F: Fail + ?Sized>(&self, fail: &F) -> Uuid;
182}
183
184impl FailureHubExt for Hub {
185 fn capture_error(&self, err: &Error) -> Uuid {
186 self.capture_event(event_from_error(err))
187 }
188
189 fn capture_fail<F: Fail + ?Sized>(&self, fail: &F) -> Uuid {
190 self.capture_event(event_from_fail(fail))
191 }
192}
193
194#[deprecated = "The `failure` integration is deprecated and will be removed in the future."]
197pub trait FailureResultExt {
198 type Value;
200 fn fallible_unwrap(self) -> Self::Value;
203}
204
205impl<T, E> FailureResultExt for Result<T, E>
206where
207 E: Into<Error>,
208{
209 type Value = T;
210 fn fallible_unwrap(self) -> Self::Value {
211 match self {
212 Ok(v) => v,
213 Err(e) => {
214 let e: Error = e.into();
215 panic!(e)
216 }
217 }
218 }
219}