Skip to content

fix(eventhubs): box the receive timeout cause once - #5103

Draft
Johnathan W (j7nw4r) wants to merge 2 commits into
mainfrom
j7nw4r/fix-eventhubs-timeout-double-box
Draft

fix(eventhubs): box the receive timeout cause once#5103
Johnathan W (j7nw4r) wants to merge 2 commits into
mainfrom
j7nw4r/fix-eventhubs-timeout-double-box

Conversation

@j7nw4r

Copy link
Copy Markdown
Member

Summary

The error that an Event Hubs receive timeout produces now carries its cause unboxed, so downcast_ref::<std::io::Error>() returns the std::io::Error with ErrorKind::TimedOut.

Motivation

azure_core::Error::new accepts E: Into<Box<dyn Error + Send + Sync>> and boxes its argument. The receive timeout in common/recoverable/receiver.rs passed an already boxed std::io::Error, so the stored cause was a Box<std::io::Error> and every downcast to std::io::Error returned None. The Debug output still printed Kind(TimedOut), so the cause looked present while the downcast failed, and a caller could not tell a receive timeout from any other I/O error.

Changes

  • Removed the Box::new around the std::io::Error cause, so Error::new boxes it once.
  • Moved the construction into RecoverableReceiver::receive_timeout_error, which gives an offline test a seam to an error that otherwise needs a live connection.
  • Added a unit test that asserts the error kind is Io and the cause downcasts to std::io::Error with ErrorKind::TimedOut.
  • Added a CHANGELOG entry under 0.15.0.

Test plan

  • A scan of every Error::new and Error::with_error call site in sdk/eventhubs and sdk/core/azure_core_amqp found this one pre-boxed cause and no other.
  • The new test was proved red against the unchanged builder: downcast_ref::<std::io::Error>() returned None.
  • cargo test --package azure_messaging_eventhubs --lib -- --test-threads=1: 145 passed, 0 failed, 14 live tests ignored.
  • RUSTFLAGS=-Dwarnings cargo test --no-run --package azure_messaging_eventhubs: exit 0.
  • cargo clippy --all-features --all-targets --package azure_messaging_eventhubs -- -Dwarnings, cargo fmt --all -- --check, RUSTDOCFLAGS=-Dwarnings cargo doc --no-deps, and cspell on the changed files: all exit 0.
  • No live test ran. The change is offline-testable, and a shared namespace was in use by other runs.

Closes #5098

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 1 pipeline(s).
3 pipeline(s) were filtered out due to trigger conditions.
There may be pipelines that require an authorized user to comment /azp run to run.

The receive timeout error is built inside an async select! arm that needs
a live connection, so no offline test can reach it. Move the construction
into a small associated function, and assert that the cause downcasts to
std::io::Error with ErrorKind::TimedOut.

The builder keeps the double box, so the new test fails until the fix
lands.

Refs #5098
azure_core::Error::new takes E: Into<Box<dyn Error + Send + Sync>> and
boxes its argument. The receive timeout passed an already boxed
std::io::Error, so the stored cause was a Box<std::io::Error> and
downcast_ref::<std::io::Error>() returned None. The Debug output still
printed Kind(TimedOut), so the cause looked present while every downcast
failed.

Pass the std::io::Error unboxed. A scan of the crate found no other
Error::new or Error::with_error call site with a pre-boxed cause.

Closes #5098
@j7nw4r
Johnathan W (j7nw4r) force-pushed the j7nw4r/fix-eventhubs-timeout-double-box branch from ea46892 to 6d349b6 Compare August 25, 2026 18:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Event Hubs] The receive timeout cause is boxed twice, so it cannot be downcast to std::io::Error

1 participant