Skip to content

Improve error reporting, exit codes, output consistency, and documentation#132

Merged
michaelklishin merged 13 commits into
rabbitmq:mainfrom
lukebakken:fix/misc
Mar 21, 2026
Merged

Improve error reporting, exit codes, output consistency, and documentation#132
michaelklishin merged 13 commits into
rabbitmq:mainfrom
lukebakken:fix/misc

Conversation

@lukebakken

Copy link
Copy Markdown
Collaborator

This PR improves error reporting and output consistency across several areas, and updates documentation for local development setup.

Error message improvements

Several CommandRunError variants were capturing useful context in their fields but not including it in the displayed message:

  • RequestError: now includes the underlying reqwest::Error detail (e.g. "connection refused", "builder error")
  • InvalidHeaderValue: now includes the underlying error detail
  • IncompatibleBody: now includes the underlying ConversionError detail
  • CertificateKeyMismatch: now includes both the cert and key file paths
  • CertificateFileCouldNotBeLoaded1 and CertificateFileCouldNotBeLoaded2 had identical messages despite representing different failure modes (PEM parse failure vs I/O read failure); they now have distinct, accurate messages
  • UnknownCommandTarget: fixed a missing closing ' in the message

Exit code mapping

report_pre_command_run_error had a _ => ExitCode::Usage catch-all that incorrectly classified runtime errors (connection failures, API errors, 404s) as usage errors. The match is now exhaustive with explicit arms for every variant. This also means the compiler will reject any future variant addition that is not explicitly handled.

Output consistency

  • The catch-all error arm in health_check_result was using println! with {:?} (Debug format). It now uses eprintln! with {} (Display format), consistent with all other error reporting paths.
  • QuietProgressReporter::finish_operation was printing a completion summary despite the reporter being intended to suppress all output. It is now a no-op.

Documentation

  • CONTRIBUTING.md: added a step-by-step Docker-based local test setup guide (start RabbitMQ, pre-configure the node, run the tests)
  • AGENTS.md: added RUSTFLAGS="-D warnings" to the nextest and clippy commands to match CI strictness; fixed cargo clippy --all to cargo clippy --all-features

Tests

All changes are covered by new unit and integration tests.

The `RequestError` variant previously displayed a static message with
no details, making it impossible to diagnose failures such as connection
refused or invalid URLs without additional tooling.

Include the underlying `reqwest::Error` in the formatted message so
the root cause is visible directly in the CLI output.
Add `CommandRunError` message formatting tests covering `RequestError`,
`InvalidHeaderValue`, and `IncompatibleBody`. The `IncompatibleBody`
test is intentionally failing until that variant is fixed next.
The catch-all error arm used `println!` with Debug format (`{:?}`),
sending raw Rust struct output to stdout. Switch to `eprintln!` with
Display format (`{}`) for consistent, human-readable error output on
stderr.

Add an integration test that verifies a connection error against an
unreachable host produces a useful message on stderr.
Replace the `_ => ExitCode::Usage` catch-all with explicit arms for
every `CommandRunError` variant. Runtime and API errors map to
`DataErr`, bad-invocation errors map to `Usage`, and
`HealthCheckFailed` maps to `Unavailable`.

The exhaustive match means the compiler will reject any future variant
addition that is not explicitly handled, preventing silent misclassification.

Add unit tests verifying that `RequestError`, `ClientError`, and
`NotFound` all produce `ExitCode::DataErr`.
Add explicit lifetime annotation to `make_handler` in the unit test
file to satisfy the `hidden_lifetime_parameters` lint under
`-D warnings` (enforced in CI).
…re mode

`CertificateFileCouldNotBeLoaded1` is a PEM parse failure; its message
now says "could not be parsed as a PEM file".

`CertificateFileCouldNotBeLoaded2` is an I/O read failure; its message
now says "could not be read".

Previously both variants had identical messages, making it impossible
to tell from the error output whether the file was unreadable or
contained invalid PEM data.
The quiet reporter is intended to suppress all output, but
`finish_operation` was printing a completion summary. Make it
consistent with all other methods by doing nothing.

Add an integration test verifying that `--quiet` produces no stdout
output when running `vhosts delete_multiple`.
Add a step-by-step guide for running the test suite locally using
Docker, covering prerequisites, starting RabbitMQ, pre-configuring
the node via `before_build.sh`, and running the tests.

Explain why `NEXTEST_RETRIES=3` is recommended. Add a node teardown
snippet. Reorganize the existing test structure and filter sections
to follow the setup guide.
…NG.md

Add `RUSTFLAGS="-D warnings"` to the nextest and clippy commands so
agents run with the same strictness as CI. Fix `cargo clippy --all`
to `cargo clippy --all-features`. Point the test node configuration
section to CONTRIBUTING.md for the full Docker setup guide.
@lukebakken lukebakken self-assigned this Mar 20, 2026
@lukebakken lukebakken added this to the 2.29.0 milestone Mar 20, 2026
Comment thread CONTRIBUTING.md Outdated
@michaelklishin michaelklishin merged commit d635682 into rabbitmq:main Mar 21, 2026
77 of 78 checks passed
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.

3 participants