use sentry::ClientOptions;
use sentry_types::Dsn;
use thiserror::Error;
#[derive(Error, Debug)]
pub enum DrCodeError {
#[error("Missing required configuration field: {0}")]
MissingField(String),
#[error("Failed to initialize Sentry: {0}")]
InitializationError(String),
}
pub struct Config {
pub public_key: String,
pub project_id: String,
pub traces_sample_rate: f32,
pub profiles_sample_rate: f32,
}
pub struct DrCode {
config: Config,
dsn: Dsn,
}
impl DrCode {
pub fn new(config: Config) -> Result<Self, DrCodeError> {
Self::validate_config(&config)?;
let dsn = Self::construct_dsn(&config)?;
Ok(Self { config, dsn })
}
fn validate_config(config: &Config) -> Result<(), DrCodeError> {
if config.public_key.is_empty() {
return Err(DrCodeError::MissingField("publicKey".to_string()));
}
if config.project_id.is_empty() {
return Err(DrCodeError::MissingField("projectId".to_string()));
}
Ok(())
}
fn construct_dsn(config: &Config) -> Result<Dsn, DrCodeError> {
let dsn_string = format!(
"https://{}@pulse.drcode.ai:443/{}",
config.public_key, config.project_id
);
dsn_string.parse::<Dsn>().map_err(|e| DrCodeError::InitializationError(e.to_string()))
}
pub fn init(&self) -> Result<(), DrCodeError> {
let options = ClientOptions {
dsn: Some(self.dsn.clone()),
traces_sample_rate: self.config.traces_sample_rate,
..Default::default()
};
let _guard = sentry::init(options);
Ok(())
}
pub fn capture_message(&self, message: &str, level: sentry::Level) {
sentry::capture_message(message, level);
}
pub fn capture_exception(&self, error: &dyn std::error::Error) {
sentry::capture_error(error);
}
}
pub fn error_handler<E>(err: E)
where
E: std::error::Error + Send + Sync + 'static,
{
sentry::capture_error(&err);
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_new_drcode() {
let config = Config {
public_key: "test_key".to_string(),
project_id: "test_project".to_string(),
traces_sample_rate: 1.0,
profiles_sample_rate: 1.0,
};
let result = DrCode::new(config);
assert!(result.is_ok());
}
#[test]
fn test_new_drcode_missing_field() {
let config = Config {
public_key: "".to_string(),
project_id: "test_project".to_string(),
traces_sample_rate: 1.0,
profiles_sample_rate: 1.0,
};
let result = DrCode::new(config);
assert!(matches!(result, Err(DrCodeError::MissingField(_))));
}
}