#![doc(html_favicon_url = "https://sentry-brand.storage.googleapis.com/favicon.ico")]
#![doc(html_logo_url = "https://sentry-brand.storage.googleapis.com/sentry-glyph-black.png")]
#![warn(missing_docs)]
#![deny(unsafe_code)]
#![warn(missing_doc_code_examples)]
#![allow(deprecated)]
use std::panic::PanicInfo;
use failure::{Error, Fail};
use sentry_backtrace::parse_stacktrace;
use sentry_core::parse_type_from_debug;
use sentry_core::protocol::{Event, Exception, Level};
use sentry_core::types::Uuid;
use sentry_core::{ClientOptions, Hub, Integration};
#[derive(Debug, Default)]
#[deprecated = "The `failure` integration is deprecated and will be removed in the future."]
pub struct FailureIntegration;
impl FailureIntegration {
pub fn new() -> Self {
Self::default()
}
}
impl Integration for FailureIntegration {
fn name(&self) -> &'static str {
"failure"
}
fn setup(&self, cfg: &mut ClientOptions) {
cfg.in_app_exclude.push("failure::");
cfg.extra_border_frames.extend_from_slice(&[
"failure::error_message::err_msg",
"failure::backtrace::Backtrace::new",
"failure::backtrace::internal::InternalBacktrace::new",
"failure::Fail::context",
]);
}
}
#[deprecated = "The `failure` integration is deprecated and will be removed in the future."]
pub fn panic_extractor(info: &PanicInfo<'_>) -> Option<Event<'static>> {
let error = info.payload().downcast_ref::<Error>()?;
Some(Event {
level: Level::Fatal,
..event_from_error(error)
})
}
#[deprecated = "The `failure` integration is deprecated and will be removed in the future."]
pub fn exception_from_single_fail<F: Fail + ?Sized>(
f: &F,
bt: Option<&failure::Backtrace>,
) -> Exception {
let dbg = format!("{:?}", f);
Exception {
ty: parse_type_from_debug(&dbg).to_owned(),
value: Some(f.to_string()),
stacktrace: bt
.map(|bt| format!("{:#?}", bt))
.and_then(|x| parse_stacktrace(&x)),
..Default::default()
}
}
#[deprecated = "The `failure` integration is deprecated and will be removed in the future."]
pub fn event_from_error(err: &failure::Error) -> Event<'static> {
let mut exceptions: Vec<_> = err
.iter_chain()
.enumerate()
.map(|(idx, cause)| {
let bt = match cause.backtrace() {
Some(bt) => Some(bt),
None if idx == 0 => Some(err.backtrace()),
None => None,
};
exception_from_single_fail(cause, bt)
})
.collect();
exceptions.reverse();
Event {
exception: exceptions.into(),
level: Level::Error,
..Default::default()
}
}
#[deprecated = "The `failure` integration is deprecated and will be removed in the future."]
pub fn event_from_fail<F: Fail + ?Sized>(fail: &F) -> Event<'static> {
let mut exceptions = vec![exception_from_single_fail(fail, fail.backtrace())];
let mut ptr: Option<&dyn Fail> = None;
while let Some(cause) = ptr.map(Fail::cause).unwrap_or_else(|| fail.cause()) {
exceptions.push(exception_from_single_fail(cause, cause.backtrace()));
ptr = Some(cause);
}
exceptions.reverse();
Event {
exception: exceptions.into(),
level: Level::Error,
..Default::default()
}
}
#[deprecated = "The `failure` integration is deprecated and will be removed in the future."]
pub fn capture_error(err: &Error) -> Uuid {
Hub::with_active(|hub| FailureHubExt::capture_error(hub.as_ref(), err))
}
#[deprecated = "The `failure` integration is deprecated and will be removed in the future."]
pub fn capture_fail<F: Fail + ?Sized>(fail: &F) -> Uuid {
Hub::with_active(|hub| hub.capture_fail(fail))
}
#[deprecated = "The `failure` integration is deprecated and will be removed in the future."]
pub trait FailureHubExt {
fn capture_error(&self, err: &Error) -> Uuid;
fn capture_fail<F: Fail + ?Sized>(&self, fail: &F) -> Uuid;
}
impl FailureHubExt for Hub {
fn capture_error(&self, err: &Error) -> Uuid {
self.capture_event(event_from_error(err))
}
fn capture_fail<F: Fail + ?Sized>(&self, fail: &F) -> Uuid {
self.capture_event(event_from_fail(fail))
}
}
#[deprecated = "The `failure` integration is deprecated and will be removed in the future."]
pub trait FailureResultExt {
type Value;
fn fallible_unwrap(self) -> Self::Value;
}
impl<T, E> FailureResultExt for Result<T, E>
where
E: Into<Error>,
{
type Value = T;
fn fallible_unwrap(self) -> Self::Value {
match self {
Ok(v) => v,
Err(e) => {
let e: Error = e.into();
panic!(e)
}
}
}
}