1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
use fastly::{http::Method, Error, Request};
use log::debug;
use url::Url;

mod types;

pub use types::*;

pub struct Raven {
    dsn: Url,
    backend: String,
}

impl Raven {
    pub fn from_dsn_and_backend(dsn: impl Into<Url>, backend: impl Into<String>) -> Self {
        Raven {
            dsn: dsn.into(),
            backend: backend.into(),
        }
    }

    pub fn report_error(
        &self,
        error: impl std::error::Error,
        request: &Request,
    ) -> Result<(), Error> {
        let event_payload = EventPayload {
            request: Some(request.into()),
            ..error.into()
        };

        let auth_string = format!(
            "Sentry sentry_version=7,sentry_key={},sentry_secret={},sentry_client={}/{}",
            self.dsn.username(),
            self.dsn.password().unwrap_or(""),
            env!("CARGO_PKG_NAME"),
            env!("CARGO_PKG_VERSION")
        );

        let req = Request::new(
            Method::POST,
            format!(
                "{}://{}/api{}/store/",
                self.dsn.scheme(),
                self.dsn.host_str().unwrap(),
                self.dsn.path()
            ),
        )
        .with_header("X-Sentry-Auth", auth_string)
        .with_body_json(&event_payload)?;

        debug!("-> Submitting report to Sentry");

        let resp = req.send(self.backend.clone())?;

        debug!("-> {} from Sentry", resp.get_status());

        Ok(())
    }
}