Skip to content

trace: adds back call to classify_eos on trailers#483

Merged
jlizen merged 4 commits into
tower-rs:mainfrom
markdingram:grpc_trailers
May 4, 2026
Merged

trace: adds back call to classify_eos on trailers#483
jlizen merged 4 commits into
tower-rs:mainfrom
markdingram:grpc_trailers

Conversation

@markdingram

@markdingram markdingram commented Apr 2, 2024

Copy link
Copy Markdown
Contributor
  • was dropped in the http-body 1.0 upgrade

Motivation

We have some tracing middleware that started as a copy of https://github.com/EmbarkStudios/server-framework/blob/main/src/middleware/trace.rs

After upgrading to tower-http 0.5.X one of the tests is failing -

https://github.com/EmbarkStudios/server-framework/blob/1bae7fe7a417443b365d2452007adfe46910037b/src/middleware/trace.rs#L205-L215

json atoms at path ".span.otel.status_code" are not equal:
    expected:
        "ERROR"
    actual:
        "OK"

Solution

Adds back call to classify_eos on trailers.

I've proven with this change the downstream tests pass once more. Notably I haven't attempted to write any tests in this repo - there was a historic desire to rewrite this middleware expessed in #365 - I would be amenable to spend some time to upstream some of the tests from https://github.com/EmbarkStudios/server-framework/blob/main/src/middleware/trace.rs if considered worthwhile by the maintainers.

jlizen added a commit to markdingram/tower-http that referenced this pull request May 4, 2026
@jlizen

jlizen commented May 4, 2026

Copy link
Copy Markdown
Member

Thanks. Also restored classify_eos(None) for the trailer-less end-of-stream case.

@jlizen jlizen merged commit ffd4d7c into tower-rs:main May 4, 2026
12 checks passed
eleboucher pushed a commit to eleboucher/towonel that referenced this pull request May 5, 2026
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [tower-http](https://github.com/tower-rs/tower-http) | workspace.dependencies | patch | `0.6.8` → `0.6.9` |

---

### Release Notes

<details>
<summary>tower-rs/tower-http (tower-http)</summary>

### [`v0.6.9`](https://github.com/tower-rs/tower-http/releases/tag/tower-http-0.6.9)

[Compare Source](tower-rs/tower-http@tower-http-0.6.8...tower-http-0.6.9)

#### Added:

- `on-early-drop`: middleware that detects when a response future or response
  body is dropped before completion ([#&#8203;636])

  Two events get hooks: the response future being dropped before
  the inner service produces a response, and the response body being
  dropped before reaching end-of-stream.

  Install custom callbacks with `OnEarlyDropLayer::builder()`:

  ```rust
  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)
          }
      }));
  ```

  Or route both events through a `trace::OnFailure` hook with
  `EarlyDropsAsFailures`. Place this layer inside a `TraceLayer` so the
  emitted events inherit the request span:

  ```rust
  use tower::ServiceBuilder;
  use tower_http::on_early_drop::{OnEarlyDropLayer, EarlyDropsAsFailures};
  use tower_http::trace::{DefaultOnFailure, TraceLayer};

  let stack = ServiceBuilder::new()
      .layer(TraceLayer::new_for_http())
      .layer(OnEarlyDropLayer::new(
          EarlyDropsAsFailures::new(DefaultOnFailure::default()),
      ));
  ```
- `fs`: make `AsyncReadBody::with_capacity` public ([#&#8203;415])

#### Changed:

- The implicit `async-compression` feature is removed ([#&#8203;642])
- The implicit `tokio` feature is removed ([#&#8203;628])
- `fs`: no longer auto-enables the `tracing` crate feature; enable `tracing`
  explicitly to restore error logging on `ServeDir` IO failures ([#&#8203;614])

#### Fixed

- `trace`: restore failure classification at end-of-stream ([#&#8203;483])
- `follow-redirect`: support unicode URLs (swaps `iri-string` dep for
  `url`) ([#&#8203;646])
- `fs`: reject reserved Windows DOS device names (`CON`, `COM1`, etc.) in
  `ServeDir` ([#&#8203;663])

[#&#8203;415]: tower-rs/tower-http#415

[#&#8203;483]: tower-rs/tower-http#483

[#&#8203;614]: tower-rs/tower-http#614

[#&#8203;628]: tower-rs/tower-http#628

[#&#8203;636]: tower-rs/tower-http#636

[#&#8203;642]: tower-rs/tower-http#642

[#&#8203;646]: tower-rs/tower-http#646

[#&#8203;663]: tower-rs/tower-http#663

#### All the PRs

- ci: update deny action to v2 by [@&#8203;seanmonstar](https://github.com/seanmonstar) in [#&#8203;627](tower-rs/tower-http#627)
- chore: improve code comments clarity by [@&#8203;xibeiyoumian](https://github.com/xibeiyoumian) in [#&#8203;626](tower-rs/tower-http#626)
- ci: Update to actions/checkout v6 by [@&#8203;tottoto](https://github.com/tottoto) in [#&#8203;629](tower-rs/tower-http#629)
- ci: msrv resolver by [@&#8203;seanmonstar](https://github.com/seanmonstar) in [#&#8203;635](tower-rs/tower-http#635)
- chore: Remove resolved cargo-deny config by [@&#8203;tottoto](https://github.com/tottoto) in [#&#8203;631](tower-rs/tower-http#631)
- ci: Update to cargo-check-external-types 0.4.0 by [@&#8203;tottoto](https://github.com/tottoto) in [#&#8203;633](tower-rs/tower-http#633)
- examples: Use typed default value clap config by [@&#8203;tottoto](https://github.com/tottoto) in [#&#8203;634](tower-rs/tower-http#634)
- examples: Disable unused reqwest feature by [@&#8203;tottoto](https://github.com/tottoto) in [#&#8203;632](tower-rs/tower-http#632)
- examples: Update to reqwest 0.13 by [@&#8203;tottoto](https://github.com/tottoto) in [#&#8203;640](tower-rs/tower-http#640)
- Fix clippy warnings in warp-key-value-store example by [@&#8203;jplatte](https://github.com/jplatte) in [#&#8203;637](tower-rs/tower-http#637)
- ci: Use Swatinem/rust-cache\@&#8203;v2 to cache by [@&#8203;tottoto](https://github.com/tottoto) in [#&#8203;644](tower-rs/tower-http#644)
- ci: Remove unused working-directory config by [@&#8203;tottoto](https://github.com/tottoto) in [#&#8203;645](tower-rs/tower-http#645)
- Use cargo-deny graph config by [@&#8203;tottoto](https://github.com/tottoto) in [#&#8203;639](tower-rs/tower-http#639)
- Fix: follow redirect unicode in [#&#8203;646](tower-rs/tower-http#646)
- doc: remove mention of deprecated bearer method in lib.rs comment by [@&#8203;VojtaStanek](https://github.com/VojtaStanek) in [#&#8203;641](tower-rs/tower-http#641)
- Allow Unicode-3.0 license by [@&#8203;tottoto](https://github.com/tottoto) in [#&#8203;648](tower-rs/tower-http#648)
- fix(docs): typo by [@&#8203;carlocorradini](https://github.com/carlocorradini) in [#&#8203;649](tower-rs/tower-http#649)
- fix: remove unused GzEncoder import in decompression in [#&#8203;647](tower-rs/tower-http#647)
- docs: update Example server in [#&#8203;652](tower-rs/tower-http#652)
- Don't automatically enable tracing for fs feature by [@&#8203;ginnyTheCat](https://github.com/ginnyTheCat) in [#&#8203;614](tower-rs/tower-http#614)
- examples: Remove unnecessary trait bound by [@&#8203;tottoto](https://github.com/tottoto) in [#&#8203;651](tower-rs/tower-http#651)
- Remove implicit async-compression feature by [@&#8203;tottoto](https://github.com/tottoto) in [#&#8203;642](tower-rs/tower-http#642)
- fix clippy warnings by [@&#8203;alexanderkjall](https://github.com/alexanderkjall) in [#&#8203;659](tower-rs/tower-http#659)
- Check for reserved DOS names by [@&#8203;Darksonn](https://github.com/Darksonn) in [#&#8203;663](tower-rs/tower-http#663)
- enable clippy for tower-http and fix current issues by [@&#8203;GlenDC](https://github.com/GlenDC) in [#&#8203;407](tower-rs/tower-http#407)
- chore: remove implicit tokio feature by [@&#8203;WaterWhisperer](https://github.com/WaterWhisperer) in [#&#8203;628](tower-rs/tower-http#628)
- trace: adds back call to classify\_eos on trailers by [@&#8203;markdingram](https://github.com/markdingram) in [#&#8203;483](tower-rs/tower-http#483)
- Make AsyncReadBody::with\_capacity public by [@&#8203;bouk](https://github.com/bouk) in [#&#8203;415](tower-rs/tower-http#415)
- examples: Use axum::body::to\_bytes by [@&#8203;tottoto](https://github.com/tottoto) in [#&#8203;650](tower-rs/tower-http#650)
- ci: Remove unnecessary protoc setup by [@&#8203;tottoto](https://github.com/tottoto) in [#&#8203;665](tower-rs/tower-http#665)
- feat(on-early-drop): Add middleware for client early drop detection by [@&#8203;fbergero](https://github.com/fbergero) in [#&#8203;636](tower-rs/tower-http#636)
- chore: release tower-http 0.6.9 by [@&#8203;jlizen](https://github.com/jlizen) in [#&#8203;666](tower-rs/tower-http#666)

#### New Contributors

- [@&#8203;xibeiyoumian](https://github.com/xibeiyoumian) made their first contribution in [#&#8203;626](tower-rs/tower-http#626)
- [@&#8203;VojtaStanek](https://github.com/VojtaStanek) made their first contribution in [#&#8203;641](tower-rs/tower-http#641)
- [@&#8203;carlocorradini](https://github.com/carlocorradini) made their first contribution in [#&#8203;649](tower-rs/tower-http#649)
- [@&#8203;ginnyTheCat](https://github.com/ginnyTheCat) made their first contribution in [#&#8203;614](tower-rs/tower-http#614)
- [@&#8203;alexanderkjall](https://github.com/alexanderkjall) made their first contribution in [#&#8203;659](tower-rs/tower-http#659)
- [@&#8203;Darksonn](https://github.com/Darksonn) made their first contribution in [#&#8203;663](tower-rs/tower-http#663)
- [@&#8203;WaterWhisperer](https://github.com/WaterWhisperer) made their first contribution in [#&#8203;628](tower-rs/tower-http#628)
- [@&#8203;bouk](https://github.com/bouk) made their first contribution in [#&#8203;415](tower-rs/tower-http#415)
- [@&#8203;fbergero](https://github.com/fbergero) made their first contribution in [#&#8203;636](tower-rs/tower-http#636)
- [@&#8203;jlizen](https://github.com/jlizen) made their first contribution in [#&#8203;666](tower-rs/tower-http#666)

**Full Changelog**: <tower-rs/tower-http@tower-http-0.6.8...tower-http-0.6.9>

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xMDEuMSIsInVwZGF0ZWRJblZlciI6IjQzLjEwMS4xIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJ0eXBlL3BhdGNoIl19-->

Reviewed-on: https://git.erwanleboucher.dev/eleboucher/towonel/pulls/33
eleboucher pushed a commit to eleboucher/towonel that referenced this pull request May 20, 2026
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [tower-http](https://github.com/tower-rs/tower-http) | workspace.dependencies | patch | `0.6.8` → `0.6.9` |

---

### Release Notes

<details>
<summary>tower-rs/tower-http (tower-http)</summary>

### [`v0.6.9`](https://github.com/tower-rs/tower-http/releases/tag/tower-http-0.6.9)

[Compare Source](tower-rs/tower-http@tower-http-0.6.8...tower-http-0.6.9)

#### Added:

- `on-early-drop`: middleware that detects when a response future or response
  body is dropped before completion ([#&#8203;636])

  Two events get hooks: the response future being dropped before
  the inner service produces a response, and the response body being
  dropped before reaching end-of-stream.

  Install custom callbacks with `OnEarlyDropLayer::builder()`:

  ```rust
  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)
          }
      }));
  ```

  Or route both events through a `trace::OnFailure` hook with
  `EarlyDropsAsFailures`. Place this layer inside a `TraceLayer` so the
  emitted events inherit the request span:

  ```rust
  use tower::ServiceBuilder;
  use tower_http::on_early_drop::{OnEarlyDropLayer, EarlyDropsAsFailures};
  use tower_http::trace::{DefaultOnFailure, TraceLayer};

  let stack = ServiceBuilder::new()
      .layer(TraceLayer::new_for_http())
      .layer(OnEarlyDropLayer::new(
          EarlyDropsAsFailures::new(DefaultOnFailure::default()),
      ));
  ```
- `fs`: make `AsyncReadBody::with_capacity` public ([#&#8203;415])

#### Changed:

- The implicit `async-compression` feature is removed ([#&#8203;642])
- The implicit `tokio` feature is removed ([#&#8203;628])
- `fs`: no longer auto-enables the `tracing` crate feature; enable `tracing`
  explicitly to restore error logging on `ServeDir` IO failures ([#&#8203;614])

#### Fixed

- `trace`: restore failure classification at end-of-stream ([#&#8203;483])
- `follow-redirect`: support unicode URLs (swaps `iri-string` dep for
  `url`) ([#&#8203;646])
- `fs`: reject reserved Windows DOS device names (`CON`, `COM1`, etc.) in
  `ServeDir` ([#&#8203;663])

[#&#8203;415]: tower-rs/tower-http#415

[#&#8203;483]: tower-rs/tower-http#483

[#&#8203;614]: tower-rs/tower-http#614

[#&#8203;628]: tower-rs/tower-http#628

[#&#8203;636]: tower-rs/tower-http#636

[#&#8203;642]: tower-rs/tower-http#642

[#&#8203;646]: tower-rs/tower-http#646

[#&#8203;663]: tower-rs/tower-http#663

#### All the PRs

- ci: update deny action to v2 by [@&#8203;seanmonstar](https://github.com/seanmonstar) in [#&#8203;627](tower-rs/tower-http#627)
- chore: improve code comments clarity by [@&#8203;xibeiyoumian](https://github.com/xibeiyoumian) in [#&#8203;626](tower-rs/tower-http#626)
- ci: Update to actions/checkout v6 by [@&#8203;tottoto](https://github.com/tottoto) in [#&#8203;629](tower-rs/tower-http#629)
- ci: msrv resolver by [@&#8203;seanmonstar](https://github.com/seanmonstar) in [#&#8203;635](tower-rs/tower-http#635)
- chore: Remove resolved cargo-deny config by [@&#8203;tottoto](https://github.com/tottoto) in [#&#8203;631](tower-rs/tower-http#631)
- ci: Update to cargo-check-external-types 0.4.0 by [@&#8203;tottoto](https://github.com/tottoto) in [#&#8203;633](tower-rs/tower-http#633)
- examples: Use typed default value clap config by [@&#8203;tottoto](https://github.com/tottoto) in [#&#8203;634](tower-rs/tower-http#634)
- examples: Disable unused reqwest feature by [@&#8203;tottoto](https://github.com/tottoto) in [#&#8203;632](tower-rs/tower-http#632)
- examples: Update to reqwest 0.13 by [@&#8203;tottoto](https://github.com/tottoto) in [#&#8203;640](tower-rs/tower-http#640)
- Fix clippy warnings in warp-key-value-store example by [@&#8203;jplatte](https://github.com/jplatte) in [#&#8203;637](tower-rs/tower-http#637)
- ci: Use Swatinem/rust-cache\@&#8203;v2 to cache by [@&#8203;tottoto](https://github.com/tottoto) in [#&#8203;644](tower-rs/tower-http#644)
- ci: Remove unused working-directory config by [@&#8203;tottoto](https://github.com/tottoto) in [#&#8203;645](tower-rs/tower-http#645)
- Use cargo-deny graph config by [@&#8203;tottoto](https://github.com/tottoto) in [#&#8203;639](tower-rs/tower-http#639)
- Fix: follow redirect unicode in [#&#8203;646](tower-rs/tower-http#646)
- doc: remove mention of deprecated bearer method in lib.rs comment by [@&#8203;VojtaStanek](https://github.com/VojtaStanek) in [#&#8203;641](tower-rs/tower-http#641)
- Allow Unicode-3.0 license by [@&#8203;tottoto](https://github.com/tottoto) in [#&#8203;648](tower-rs/tower-http#648)
- fix(docs): typo by [@&#8203;carlocorradini](https://github.com/carlocorradini) in [#&#8203;649](tower-rs/tower-http#649)
- fix: remove unused GzEncoder import in decompression in [#&#8203;647](tower-rs/tower-http#647)
- docs: update Example server in [#&#8203;652](tower-rs/tower-http#652)
- Don't automatically enable tracing for fs feature by [@&#8203;ginnyTheCat](https://github.com/ginnyTheCat) in [#&#8203;614](tower-rs/tower-http#614)
- examples: Remove unnecessary trait bound by [@&#8203;tottoto](https://github.com/tottoto) in [#&#8203;651](tower-rs/tower-http#651)
- Remove implicit async-compression feature by [@&#8203;tottoto](https://github.com/tottoto) in [#&#8203;642](tower-rs/tower-http#642)
- fix clippy warnings by [@&#8203;alexanderkjall](https://github.com/alexanderkjall) in [#&#8203;659](tower-rs/tower-http#659)
- Check for reserved DOS names by [@&#8203;Darksonn](https://github.com/Darksonn) in [#&#8203;663](tower-rs/tower-http#663)
- enable clippy for tower-http and fix current issues by [@&#8203;GlenDC](https://github.com/GlenDC) in [#&#8203;407](tower-rs/tower-http#407)
- chore: remove implicit tokio feature by [@&#8203;WaterWhisperer](https://github.com/WaterWhisperer) in [#&#8203;628](tower-rs/tower-http#628)
- trace: adds back call to classify\_eos on trailers by [@&#8203;markdingram](https://github.com/markdingram) in [#&#8203;483](tower-rs/tower-http#483)
- Make AsyncReadBody::with\_capacity public by [@&#8203;bouk](https://github.com/bouk) in [#&#8203;415](tower-rs/tower-http#415)
- examples: Use axum::body::to\_bytes by [@&#8203;tottoto](https://github.com/tottoto) in [#&#8203;650](tower-rs/tower-http#650)
- ci: Remove unnecessary protoc setup by [@&#8203;tottoto](https://github.com/tottoto) in [#&#8203;665](tower-rs/tower-http#665)
- feat(on-early-drop): Add middleware for client early drop detection by [@&#8203;fbergero](https://github.com/fbergero) in [#&#8203;636](tower-rs/tower-http#636)
- chore: release tower-http 0.6.9 by [@&#8203;jlizen](https://github.com/jlizen) in [#&#8203;666](tower-rs/tower-http#666)

#### New Contributors

- [@&#8203;xibeiyoumian](https://github.com/xibeiyoumian) made their first contribution in [#&#8203;626](tower-rs/tower-http#626)
- [@&#8203;VojtaStanek](https://github.com/VojtaStanek) made their first contribution in [#&#8203;641](tower-rs/tower-http#641)
- [@&#8203;carlocorradini](https://github.com/carlocorradini) made their first contribution in [#&#8203;649](tower-rs/tower-http#649)
- [@&#8203;ginnyTheCat](https://github.com/ginnyTheCat) made their first contribution in [#&#8203;614](tower-rs/tower-http#614)
- [@&#8203;alexanderkjall](https://github.com/alexanderkjall) made their first contribution in [#&#8203;659](tower-rs/tower-http#659)
- [@&#8203;Darksonn](https://github.com/Darksonn) made their first contribution in [#&#8203;663](tower-rs/tower-http#663)
- [@&#8203;WaterWhisperer](https://github.com/WaterWhisperer) made their first contribution in [#&#8203;628](tower-rs/tower-http#628)
- [@&#8203;bouk](https://github.com/bouk) made their first contribution in [#&#8203;415](tower-rs/tower-http#415)
- [@&#8203;fbergero](https://github.com/fbergero) made their first contribution in [#&#8203;636](tower-rs/tower-http#636)
- [@&#8203;jlizen](https://github.com/jlizen) made their first contribution in [#&#8203;666](tower-rs/tower-http#666)

**Full Changelog**: <tower-rs/tower-http@tower-http-0.6.8...tower-http-0.6.9>

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xMDEuMSIsInVwZGF0ZWRJblZlciI6IjQzLjEwMS4xIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJ0eXBlL3BhdGNoIl19-->

Reviewed-on: https://git.erwanleboucher.dev/eleboucher/towonel/pulls/33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants