Skip to content

refactor: unify request errors + add audit log middleware#328

Merged
Destynova2 merged 1 commit into
mainfrom
refactor/unified-error-and-audit-middleware-claude-v2
Apr 28, 2026
Merged

refactor: unify request errors + add audit log middleware#328
Destynova2 merged 1 commit into
mainfrom
refactor/unified-error-and-audit-middleware-claude-v2

Conversation

@Destynova2
Copy link
Copy Markdown
Contributor

Summary

  • Replaces the AppError + ProviderError split with a single RequestError enum that carries the upstream HTTP status verbatim (502/503/504) instead of flattening every provider failure to a generic 502 body. New variants: BadRequest, Unauthorized, Forbidden, NotFound, ParseError, RoutingError, RateLimited{provider, retry_after_ms}, ProviderUpstream{provider, status, body}, BudgetExceeded{limit_usd, actual_usd}, DlpBlocked, AuthRevoked, Internal(anyhow::Error).
  • RequestError::is_retryable() is the canonical retry classifier — removes three duplicate 429 detectors from dispatch/retry.rs and centralises the matcher.
  • Adds an Axum audit-log middleware (audit_log_layer) that emits AuditEvent::RequestProcessed for every request — including OAuth, config, and error paths that previously bypassed audit entirely. De-dupes via the AuditedAlready response-extension marker so the dispatch pipeline (which writes a richer DLP/risk/token-aware entry) is the single source of truth on the hot path. Closes the audit gap that allowed silent model enumeration via DLP probes (EU AI Act Article 6 / PCI DSS 3.4).

The task brief asked for fix/preset-mod-include-str as the base; that branch was merged into main on 2026-04-27 and deleted, so the PR retargets main. The branch was rebased onto current main (2a5f744) so the diff is exactly the intended change set.

Test plan

  • cargo check (default features, all features, no-default-features)
  • cargo clippy --tests --all-targets -- -D warnings
  • cargo fmt --check
  • cargo nextest run — 1357/1357 tests pass on rebased branch
  • 35 unit tests for RequestError::IntoResponse and is_retryable() covering every variant
  • 9 integration tests for audit middleware (status codes, AuditedAlready de-dup, provider header, error variant tag, risk levels, anonymous fallback)
  • 9 snapshot tests for error response JSON shapes

🤖 Generated with Claude Code

Replaces the `AppError` + `ProviderError` split with a single
`RequestError` enum that carries the upstream HTTP status verbatim
(502/503/504) instead of flattening every provider failure to a
generic 502 body. Introduces the canonical `RequestError::is_retryable`
classifier as the single source of truth for retry/backoff decisions
and removes three duplicate 429 detectors from `dispatch/retry.rs`.

Also adds an Axum audit-log middleware (`audit_log_layer`) that emits
an `AuditEvent::RequestProcessed` entry for every request lifecycle —
including OAuth, config, and error paths that previously bypassed
audit entirely. Uses an `AuditedAlready` response-extension marker so
the dispatch path (which writes a richer DLP/risk/token-aware entry)
is not double-logged. Closes the audit gap that allowed silent model
enumeration via DLP probes (EU AI Act Article 6 / PCI DSS 3.4).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@Destynova2 Destynova2 enabled auto-merge April 28, 2026 21:05
@Destynova2 Destynova2 merged commit ce1b114 into main Apr 28, 2026
42 checks passed
@Destynova2 Destynova2 deleted the refactor/unified-error-and-audit-middleware-claude-v2 branch April 28, 2026 21:16
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.

1 participant