Skip to content

iter-27: fix 5 bugs surfaced by dogfooding 2026-05-10#32

Merged
ractive merged 2 commits into
mainfrom
iter-27/dogfooding-bugfixes
May 10, 2026
Merged

iter-27: fix 5 bugs surfaced by dogfooding 2026-05-10#32
ractive merged 2 commits into
mainfrom
iter-27/dogfooding-bugfixes

Conversation

@ractive

@ractive ractive commented May 10, 2026

Copy link
Copy Markdown
Owner

Summary

Five independent correctness fixes from the 2026-05-10 dogfooding round:

  • container logs clap panic — dropped the per-command --format field that collided with the global flag; hoppy container logs --app-id … now parses cleanly.
  • DNS zone scan results null — added a null_to_empty_vec serde helper so an in-flight scan returning "Records": null deserialises to an empty vec instead of panicking.
  • pull-zone optimizer-classes 400 — bunny.net expects the field as a JSON-string-encoded map on the request side; added a serialize_with helper. CLI flag is unchanged.
  • shield API error envelope — parse the nested {error: {statusCode, errorKey, message}} shape uniformly across all shield modules; replaces Shield API error 0: unknown with the real status + key + message.
  • db config optimal-single — endpoint is broken upstream (responds with a CDN-shaped query-string error). Hidden behind #[command(hide = true)] and now bails with a clean message.

Each fix has a regression test (unit or wiremock-based).

Test plan

  • cargo fmt
  • cargo clippy --workspace --all-targets -- -D warnings
  • cargo test --workspace --quiet (all green)
  • Dogfooding follow-up against the live account

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes

    • Fixed crash when running container logs; global --format now works and table/text output is accepted.
    • DNS zone scans tolerate null records during in-progress scans.
    • Shield API errors now surface correct status codes and detailed messages.
    • db config optimal-single reports upstream unavailability instead of failing.
  • Documentation

    • Added backlog entries and iteration notes documenting planned CLI UX and output improvements.

Review Change Stack

- container logs: drop per-command --format that collided with the
  global flag and crashed clap before any work ran.
- DNS zone scan results: tolerate "Records": null while a scan is
  in flight via a null-to-empty-vec serde helper.
- pull-zone update --optimizer-classes: send the field as a JSON
  string (matches bunny.net's wire format; response side already
  tolerated either shape).
- shield API errors: parse the nested {error: {statusCode, errorKey,
  message}} envelope and surface the real status + key + message
  uniformly across all shield modules.
- db config optimal-single: hide the subcommand and bail with a
  clean message — endpoint is broken upstream.

Includes regression tests for each fix.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@ractive
ractive requested a review from Copilot May 10, 2026 16:33
@coderabbitai

coderabbitai Bot commented May 10, 2026

Copy link
Copy Markdown

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Free

Run ID: b47454ac-a9f1-410f-b2c4-08253a3fbe2f

📥 Commits

Reviewing files that changed from the base of the PR and between 71b5c46 and 3b4849d.

📒 Files selected for processing (8)
  • crates/bunny-api-shield/src/types.rs
  • hoppy-knowledgebase/backlog/container-logs-clap-panic.md
  • hoppy-knowledgebase/backlog/db-config-optimal-single-broken.md
  • hoppy-knowledgebase/backlog/db-delete-output-format.md
  • hoppy-knowledgebase/backlog/numeric-enum-flags.md
  • hoppy-knowledgebase/backlog/stream-library-stats-engagement-minus-one.md
  • hoppy-knowledgebase/iterations/iteration-28-dogfooding-ux-polish.md
  • src/commands/container.rs

📝 Walkthrough

Walkthrough

This PR packages five localized dogfooding bugfixes from May 2026, plus comprehensive backlog documentation and iteration planning. Fixes address DNS null-record deserialization panic, Shield API nested error-envelope parsing, container logs clap argument collision, and a broken DB config endpoint. Also includes extensive UX friction documentation and iteration-28 scope for CLI flag/output consistency cleanup.

Changes

Dogfooding Bugfixes and Planning

Layer / File(s) Summary
Serde Helper & DNS Null Records
crates/bunny-api-core/src/serde_helpers.rs, crates/bunny-api-core/src/types.rs
New null_to_empty_vec serde helper converts JSON null to empty Vec<T>; applied to DnsRecordScanResult.records to handle pending scans returning Records: null. Unit tests verify null, missing, and populated records.
Shield Error Envelope Types
crates/bunny-api-shield/src/types.rs
Introduces ShieldApiErrorInner and ShieldApiErrorEnvelope structs for nested error parsing, plus parse_shield_error function that deserializes nested error envelope first, then falls back to RFC 7807 ProblemDetails. Includes parse success, fallback, and display formatting tests.
Shield Error Public API
crates/bunny-api-shield/src/lib.rs
Re-exports ShieldApiErrorEnvelope, ShieldApiErrorInner, and parse_shield_error for public library use.
Shield Client Error Handling
crates/bunny-api-shield/src/client.rs
Refactors HTTP error handling in ShieldClient to use parse_shield_error(&bytes) across all three error paths: handle_response, handle_empty_response, and get_promo_state. Updates imports and error-handling documentation.
Container Logs Clap Panic Fix
src/cli.rs, src/commands/container.rs
Removes subcommand-level --format argument from container logs to eliminate clap downcasting collision; command now uses global --format option. Updates dispatch to pass OutputFormat directly to handler. Adds regression test for successful parse with/without global --format json.
DB Config Optimal-Single Error
src/cli.rs, src/commands/database.rs
Hides broken db config optimal-single subcommand from CLI help; handle_config now immediately bails with error message stating upstream endpoint missing required cdn_server_token field.
Backlog: Dogfooding Issues
hoppy-knowledgebase/backlog/container-logs-clap-panic.md, hoppy-knowledgebase/backlog/dns-scan-results-null-records.md, hoppy-knowledgebase/backlog/shield-api-error-mapping.md, hoppy-knowledgebase/backlog/db-config-optimal-single-broken.md, hoppy-knowledgebase/backlog/optimizer-classes-rejected.md
Documents five discovered issues: panic during container logs argument parsing, DNS deserialization on pending scan null records, Shield error envelope mismatch, DB config upstream failure, pull-zone optimizer-classes rejection. Each includes repro, hypothesis, and proposed fix.
Backlog: CLI Friction Items
hoppy-knowledgebase/backlog/date-format-friction.md, hoppy-knowledgebase/backlog/flag-naming-consistency.md, hoppy-knowledgebase/backlog/numeric-enum-flags.md, hoppy-knowledgebase/backlog/dnssec-status-text-output-thin.md, hoppy-knowledgebase/backlog/stream-library-stats-engagement-minus-one.md, hoppy-knowledgebase/backlog/auth-login-missing-from-cli.md, hoppy-knowledgebase/backlog/db-delete-output-format.md
Identifies seven UX friction points: date/time flag format inconsistencies and poor errors, flag naming asymmetries across storage/stream/db commands, numeric enum flags showing raw integers, DNSSEC status omitting DS record in text mode, stream statistics -1 sentinel handling, auth playbook mismatch with actual CLI, and db delete/group delete confirmation output thinness.
Iteration Planning & Acceptance
hoppy-knowledgebase/iterations/iteration-27-dogfooding-bugfixes.md, hoppy-knowledgebase/iterations/iteration-28-dogfooding-ux-polish.md
Iteration-27 finalizes five critical bugfixes with scope, acceptance criteria (regression tests, lint/format/test CI, dogfooding re-verification), and related references. Iteration-28 plans seven UX polish items: flag naming standardization, enum display values, date/time input flexibility with clear errors, delete confirmation formats, DNSSEC DS record inclusion, -1 sentinel rendering, and auth playbook alignment. Acceptance criteria and related links included.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

A rabbit hopped through bugs with care,
Five fixes scattered here and there—
From DNS null to Shield's nested dance,
Container logs, and DB's second chance.
Now backlog blooms with iteration's plan,
Spring cleanup ready, hop and scan! 🐰✨


Note

🎁 Summarized by CodeRabbit Free

Your organization is on the Free plan. CodeRabbit will generate a high-level summary and a walkthrough for each pull request. For a comprehensive line-by-line review, please upgrade your subscription to CodeRabbit Pro by visiting https://app.coderabbit.ai/login.

Comment @coderabbitai help to get the list of available commands and usage tips.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR bundles several dogfooding-driven correctness fixes across the CLI and API client crates, focusing on preventing panics, tolerating inconsistent upstream payloads, and improving Shield API error reporting.

Changes:

  • Removed the container logs subcommand’s local --format flag to avoid a clap type-collision, and added parse regression tests.
  • Made DNS scan results deserialization tolerate "Records": null by adding a serde helper and regression tests.
  • Added Shield API nested error-envelope parsing (with RFC7807 fallback) and wired it into the Shield client, plus unit tests.
  • Hid the broken db config optimal-single subcommand and replaced the call with a clean error message.
  • Added iteration/backlog knowledgebase entries documenting the dogfooding findings.

Reviewed changes

Copilot reviewed 23 out of 23 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
tests/e2e/snapshots/e2e__cli_container__container_logs_help.snap Updates CLI help snapshot for container logs after argument changes.
src/commands/database.rs Replaces optimal-single execution with a clean bail message.
src/commands/container.rs Removes per-command --format usage and validates the global output format for log streaming.
src/cli.rs Drops the conflicting container logs --format, hides OptimalSingle, and adds CLI parse regression tests.
hoppy-knowledgebase/iterations/iteration-28-dogfooding-ux-polish.md New iteration planning doc (UX polish follow-up).
hoppy-knowledgebase/iterations/iteration-27-dogfooding-bugfixes.md New iteration doc documenting the bugfix scope and acceptance.
hoppy-knowledgebase/backlog/*.md New backlog entries capturing dogfooding issues.
crates/bunny-api-shield/src/types.rs Adds nested Shield error envelope types + parse_shield_error and associated tests.
crates/bunny-api-shield/src/lib.rs Re-exports new Shield error types/helpers.
crates/bunny-api-shield/src/client.rs Uses parse_shield_error when mapping non-success responses.
crates/bunny-api-core/src/types.rs Applies null_to_empty_vec to DNS scan records and adds regression tests.
crates/bunny-api-core/src/serde_helpers.rs Introduces null_to_empty_vec helper with unit tests.

Comment thread src/commands/container.rs Outdated
Comment on lines 2135 to 2143
// --- 1. Validate format ---------------------------------------------------
// Reject --format table: tail output is a live stream, not tabular data.
let logs_format = match format {
"text" => LogsFormat::Text,
"json" => LogsFormat::Json,
"table" => bail!(
OutputFormat::Text => LogsFormat::Text,
OutputFormat::Json => LogsFormat::Json,
OutputFormat::Table => bail!(
"`hoppy container logs` does not support --format table; \
tail output is not tabular. Use --format text (default) or --format json."
),
Comment on lines +507 to +512
if let Ok(env) = serde_json::from_slice::<ShieldApiErrorEnvelope>(bytes) {
return Some(anyhow::anyhow!(env));
}
if let Ok(problem) = serde_json::from_slice::<ProblemDetails>(bytes) {
return Some(anyhow::anyhow!(problem));
}
- container logs: map global --format=table (the default) to text
  rather than bailing — the previous validation made the command
  fail on every default invocation.
- shield parse_shield_error: only accept the ProblemDetails fallback
  when at least one RFC 7807 field is present, so non-7807 bodies
  fall through to status + raw body instead of "error 0: unknown".
- knowledgebase: doc consistency tweaks flagged by CodeRabbit
  (deserialize spelling, sibling/shield typo, db-delete JSON shape,
  -1 sentinel handling, iter-28 acceptance checkboxes).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@ractive
ractive merged commit 97a2662 into main May 10, 2026
4 of 8 checks passed
@ractive
ractive deleted the iter-27/dogfooding-bugfixes branch May 10, 2026 16:40
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