Skip to content

refactor(vtn): split AppError into a pure to_problem() + thin axum adapter - #492

Merged
stefanvi merged 1 commit into
OpenLEADR:mainfrom
cacoco:ccoco/vtn-error-to-problem-split
Sep 11, 2026
Merged

refactor(vtn): split AppError into a pure to_problem() + thin axum adapter#492
stefanvi merged 1 commit into
OpenLEADR:mainfrom
cacoco:ccoco/vtn-error-to-problem-split

Conversation

@cacoco

@cacoco cacoco commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Splits AppError's axum IntoResponse impl into two concerns: a pure
    pub(crate) fn into_problem(self) -> (StatusCode, Problem) that maps every
    variant to an RFC 7807 problem body, and a thin impl IntoResponse for
    AppError that calls it and builds the axum Response (including the
    WWW-Authenticate header on 401s, preserved exactly as before).
  • StatusCode here is http::StatusCode and Problem is a plain
    openleadr_wire::problem::Problem, both already framework-neutral types,
    so this is pure code motion: the match self { ... } body moves
    byte-for-byte from into_response into into_problem, with no arm's logic,
    log level, or message text changed.
  • Motivation: today the only way to get a status code and problem body out of
    an AppError is axum's IntoResponse. Separating "what does this error map
    to" from "how does axum render that" means the mapping can be reused by
    any adapter around AppError, not just axum's, keeping the RFC 7807
    semantics in one place instead of duplicated per framework.
  • Named into_problem, not to_problem: clippy::wrong_self_convention flags a
    to_* method taking a non-Copy self by value, and into_* is the correct
    naming convention for a method that consumes self.
  • into_problem is pub(crate), so this isn't a public API change; nothing
    outside the crate can observe the split.

Test plan

  • cargo test -p openleadr-vtn --features live-db-test,compression-br,compression-gzip,experimental-websockets -- --test-threads=1: 190 passed, 0 failed, 2 ignored (pre-existing, unrelated to this change).
  • cargo +nightly fmt --all --check -- --config imports_granularity="Crate"
  • cargo clippy -p openleadr-vtn --lib --all-features -- -D warnings
  • Verified the 401 WWW-Authenticate header logic survived the split: api::user::test::delete_credential and delete_user assert its exact value and both pass unchanged.
  • Verified api::test::unsupported_media_type, api::test::not_found, and api::test::method_not_allowed (each exercising a distinct AppError variant's status/detail mapping) pass unchanged.

@cacoco
cacoco force-pushed the ccoco/vtn-error-to-problem-split branch from ae8cffa to 20f4b8c Compare August 24, 2026 16:15
@codecov

codecov Bot commented Aug 25, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 86.39%. Comparing base (68238f3) to head (59edabd).

Additional details and impacted files
@@           Coverage Diff           @@
##             main     #492   +/-   ##
=======================================
  Coverage   86.38%   86.39%           
=======================================
  Files          50       50           
  Lines        7309     7313    +4     
=======================================
+ Hits         6314     6318    +4     
  Misses        995      995           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@cacoco
cacoco force-pushed the ccoco/vtn-error-to-problem-split branch 2 times, most recently from 64788ff to 312c10d Compare September 3, 2026 13:58
@cacoco

cacoco commented Sep 3, 2026

Copy link
Copy Markdown
Contributor Author

@stefanvi would love if you could take a look, thanks!

@cacoco
cacoco force-pushed the ccoco/vtn-error-to-problem-split branch from 312c10d to 4d892e3 Compare September 4, 2026 21:56
Comment thread openleadr-vtn/src/error.rs Outdated
@cacoco
cacoco force-pushed the ccoco/vtn-error-to-problem-split branch from 4d892e3 to 8f00630 Compare September 7, 2026 18:32
Phase 1 of decoupling openleadr-vtn's HTTP layer from axum. AppError's
IntoResponse impl mixed two concerns: computing the (StatusCode, Problem)
pair for each error variant, and building an axum Response from it. Only
the second part is actually axum-specific: StatusCode is http::StatusCode
and Problem is a plain openleadr_wire type, so the mapping itself was
already framework-neutral data.

into_problem(self) -> (StatusCode, Problem) is the extracted pure function;
IntoResponse now just calls it and adds the WWW-Authenticate header on 401,
unchanged. Named into_problem, not to_problem, because it consumes self:
clippy::wrong_self_convention flags a to_* method taking a non-Copy self by
value, and into_* is the correct convention for a consuming conversion.

This lets the RFC7807 mapping be reused by any adapter around AppError, not
just axum's, instead of being re-implemented per framework.

No behavior change, verified against the full openleadr-vtn test suite
(190 passed, 0 failed, 2 pre-existing ignores).

Signed-off-by: Christopher Coco <cacoco@gmail.com>
@cacoco
cacoco force-pushed the ccoco/vtn-error-to-problem-split branch from 8f00630 to 59edabd Compare September 7, 2026 18:39
@stefanvi
stefanvi added this pull request to the merge queue Sep 11, 2026
Merged via the queue into OpenLEADR:main with commit ba6106b Sep 11, 2026
15 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.

2 participants