diff --git a/sentry-tower/src/http.rs b/sentry-tower/src/http.rs index 5ad964626..ee159a99a 100644 --- a/sentry-tower/src/http.rs +++ b/sentry-tower/src/http.rs @@ -4,6 +4,7 @@ use std::pin::Pin; use std::task::{Context, Poll}; use http::{header, uri, Request, Response, StatusCode}; +use pin_project::pinned_drop; use sentry_core::protocol; use tower_layer::Layer; use tower_service::Service; @@ -62,7 +63,7 @@ impl Layer for SentryHttpLayer { } /// The Future returned from [`SentryHttpService`]. -#[pin_project::pin_project] +#[pin_project::pin_project(PinnedDrop)] pub struct SentryHttpFuture { on_first_poll: Option<( sentry_core::protocol::Request, @@ -123,6 +124,23 @@ where } } +#[pinned_drop] +impl PinnedDrop for SentryHttpFuture { + fn drop(self: Pin<&mut Self>) { + let slf = self.project(); + + // If the future gets dropped without being polled to completion, + // still finish the transaction to make sure this is not lost. + if let Some((transaction, parent_span)) = slf.transaction.take() { + if transaction.get_status().is_none() { + transaction.set_status(protocol::SpanStatus::Aborted); + } + transaction.finish(); + sentry_core::configure_scope(|scope| scope.set_span(parent_span)); + } + } +} + impl Service> for SentryHttpService where S: Service, Response = Response>,