worker_cf_sentry/
client.rsuse crate::toucan_sys;
use worker::js_sys;
macro_rules! set {
($obj:expr, $k:expr, $v:expr) => {
js_sys::Reflect::set(&$obj, &$k.into(), &$v.into()).unwrap();
};
}
pub struct SentryConfig {
dsn: String,
environment: Option<String>,
cf_access_client_id: String,
cf_access_client_secret: String,
}
impl SentryConfig {
pub fn from_env(env: &worker::Env) -> Result<Self, worker::Error> {
let dsn = env.var("SENTRY_DSN")?.to_string();
let environment = env.var("SENTRY_ENVIRONMENT").ok().map(|v| v.to_string());
let cf_access_client_id = env.var("SENTRY_CF_ACCESS_CLIENT_ID")?.to_string();
let cf_access_client_secret = env.secret("SENTRY_CF_ACCESS_CLIENT_SECRET")?.to_string();
Ok(Self {
dsn,
environment,
cf_access_client_id,
cf_access_client_secret,
})
}
}
pub struct SentryClient {
inner: toucan_sys::Toucan,
}
impl SentryClient {
pub fn new(
config: SentryConfig,
request: &worker::Request,
context: &worker::Context,
) -> SentryClient {
let transport_options_headers = js_sys::Object::new();
set!(
transport_options_headers,
"CF-Access-Client-ID",
config.cf_access_client_id
);
set!(
transport_options_headers,
"CF-Access-Client-Secret",
config.cf_access_client_secret
);
let transport_options = js_sys::Object::new();
set!(transport_options, "headers", transport_options_headers);
let args = js_sys::Object::new();
set!(args, "dsn", config.dsn);
set!(args, "transportOptions", transport_options);
let allowed_headers = js_sys::Array::new();
allowed_headers.push(&"user-agent".into());
allowed_headers.push(&"accept-encoding".into());
allowed_headers.push(&"accept-language".into());
allowed_headers.push(&"cf-ray".into());
allowed_headers.push(&"content-length".into());
allowed_headers.push(&"content-type".into());
allowed_headers.push(&"x-real-ip".into());
allowed_headers.push(&"host".into());
set!(args, "allowedHeaders", allowed_headers);
js_sys::Reflect::set(&args, &"request".into(), request.inner()).unwrap();
js_sys::Reflect::set(&args, &"context".into(), context.as_ref()).unwrap();
set!(args, "debug", false);
if let Some(ref environment) = config.environment {
set!(args, "environment", environment);
}
let toucan = toucan_sys::Toucan::new(args);
SentryClient { inner: toucan }
}
pub fn set_tag(&self, key: &str, value: &str) {
self.inner.set_tag(key, value);
}
pub fn set_context(&self, name: &str, value: js_sys::Object) {
self.inner.set_context(name, value);
}
pub fn capture_message(&self, message: &str) {
self.inner.capture_message(message);
}
pub fn capture_exception<T: std::error::Error + ?Sized>(&self, error: &T) {
let js_error = js_sys::Error::new(&error.to_string());
self.inner.capture_exception(js_error);
}
pub fn capture_js_error(&self, js_error: js_sys::Error) {
self.inner.capture_exception(js_error);
}
}