Skip to main content

Module on_early_drop

Module on_early_drop 

Source
Available on crate feature on-early-drop only.
Expand description

Middleware that detects when a response future or response body is dropped before completion.

HTTP services typically learn nothing when a client disconnects mid-request. This middleware installs drop guards so that premature termination is observable: logs, metrics, cleanup.

Two events are distinguished:

  • Future drop: the response future was dropped before the inner service produced any response.
  • Body drop: the response body was dropped before reaching is_end_stream.

§Example: bridge to trace::OnFailure

With the trace feature, EarlyDropsAsFailures wraps any OnFailure<DroppedFailure> and routes both events through it. Place this layer inside TraceLayer so that the emitted events inherit the request span.

use tower_http::on_early_drop::{OnEarlyDropLayer, EarlyDropsAsFailures};
use tower_http::trace::DefaultOnFailure;

let layer = OnEarlyDropLayer::new(
    EarlyDropsAsFailures::new(DefaultOnFailure::default()),
);

Use OnEarlyDropLayer::builder to place EarlyDropsAsFailures in a single slot (track only body or only future drops) or to install plain closures.

§Example: builder with direct callbacks

Use OnEarlyDropLayer::builder to install closures in either or both slots. The future-drop closure is a factory: outer closure runs at request time, inner closure fires on drop. The body-drop closure uses a three-level chain via OnBodyDropFn: outer at request time, middle at response-ready time, inner on drop.

use http::Request;
use tower_http::on_early_drop::{OnBodyDropFn, OnEarlyDropLayer};

let layer = OnEarlyDropLayer::builder()
    .on_future_drop(|req: &Request<()>| {
        let uri = req.uri().clone();
        move || eprintln!("future dropped for {}", uri)
    })
    .on_body_drop(OnBodyDropFn::new(|req: &Request<()>| {
        let uri = req.uri().clone();
        move |parts: &http::response::Parts| {
            let status = parts.status;
            move || eprintln!("body dropped for {} status {}", uri, status)
        }
    }));

Chain just one of the two methods to hook only that event; the other slot stays no-op.

§Panics in callbacks

Callbacks fire from Drop. Panicking during a drop that occurs while another panic is unwinding aborts the process. Closures and custom OnDropCallback implementations must not panic.

§Standalone guard

OnEarlyDropGuard is usable on its own to detect early drop of arbitrary scopes.

use tower_http::on_early_drop::OnEarlyDropGuard;

let mut guard = OnEarlyDropGuard::new(|| {
    eprintln!("scope exited early");
});
// ... work that might return early ...
guard.completed();

Structs§

BodyDropFailureCallbacktrace
Body-drop callback produced by EarlyDropsAsFailures.
BodyDropped
Context for DroppedFailure::Body.
EarlyDropsAsFailurestrace
Bridges early-drop events to trace::OnFailure.
FutureDropFailureCallbacktrace
Future-drop callback produced by EarlyDropsAsFailures.
FutureDropped
Context for DroppedFailure::Future.
NoopDropCallback
No-op callback used as the default for empty hook slots.
OnBodyDropFn
Adapter making FnMut(&Request) -> FnOnce(&Parts) -> FnOnce() closure chains implement OnBodyDrop.
OnEarlyDropBody
Response body for OnEarlyDropService. Fires its callback if dropped before reaching end-of-stream.
OnEarlyDropFuture
Response future for OnEarlyDropService.
OnEarlyDropGuard
Runs a callback on drop unless completed is called first.
OnEarlyDropLayer
Layer that applies OnEarlyDropService.
OnEarlyDropService
Service produced by OnEarlyDropLayer.
PreResponseBodyDropCallbacktrace
Intermediate produced by OnBodyDrop::make_at_call for EarlyDropsAsFailures, carrying state forward to OnBodyDrop::make_at_response.

Enums§

DroppedFailure
Classification for early-drop events reported through EarlyDropsAsFailures.

Traits§

OnBodyDrop
Hook fired when the response body is dropped before reaching end-of-stream.
OnDropCallback
Callback fired exactly once when an early-drop event is observed.
OnFutureDrop
Hook fired when the response future is dropped before producing a result.