use anyhow::anyhow;
use sentry_core::Hub;
use std::any::Any;
use std::future::Future;
use std::panic::PanicHookInfo;
pub(crate) async fn with_sentry_transaction<F, R, E, Fut>(
transaction_name: &str,
callback: F,
) -> Result<R, E>
where
F: FnOnce() -> Fut,
Fut: Future<Output = Result<R, E>>,
{
let hub = Hub::new_from_top(Hub::current());
let _scope_guard = hub.push_scope();
let tx_ctx = sentry_core::TransactionContext::new(transaction_name, "workers.perform");
let tx = sentry_core::start_transaction(tx_ctx);
hub.configure_scope(|scope| scope.set_span(Some(tx.clone().into())));
let result = callback().await;
tx.set_status(if result.is_ok() {
sentry_core::protocol::SpanStatus::Ok
} else {
sentry_core::protocol::SpanStatus::UnknownError
});
tx.finish();
result
}
pub(crate) fn try_to_extract_panic_info(info: &(dyn Any + Send + 'static)) -> anyhow::Error {
info.downcast_ref::<PanicHookInfo<'_>>().map_or_else(
|| {
if let Some(x) = info.downcast_ref::<&'static str>() {
anyhow!("job panicked: {x}")
} else if let Some(x) = info.downcast_ref::<String>() {
anyhow!("job panicked: {x}")
} else {
anyhow!("job panicked")
}
},
|x| anyhow!("job panicked: {x}"),
)
}