Preserve typed handler error category through dispatch (#83) #86

Merged
timur merged 4 commits from issue-83-error-categories into development 2026-05-20 08:16:42 +00:00
Owner

Closes #83. RpcErrorKind + new RpcError variants (Invalid/NotFound/PermissionDenied) so typed category survives. Generator emits category() on service-error enums + tagged glue. Dispatch maps Invalid → -32602, NotFound → -32602, PermissionDenied → -32000, Internal/Operation → -32603. Fixes the misleading 'Redis operation error:' prefix on non-Redis failures. 77 lib tests + 6 recipe_server tests pass; integration tests cover validation → -32602 round trip.

Closes #83. RpcErrorKind + new RpcError variants (Invalid/NotFound/PermissionDenied) so typed category survives. Generator emits category() on service-error enums + tagged glue. Dispatch maps Invalid → -32602, NotFound → -32602, PermissionDenied → -32000, Internal/Operation → -32603. Fixes the misleading 'Redis operation error:' prefix on non-Redis failures. 77 lib tests + 6 recipe_server tests pass; integration tests cover validation → -32602 round trip.
feat(rpc): typed error categories survive dispatch (#83)
Some checks failed
Test / test (push) Has been cancelled
7d37514e26
Issue #83: every business/validation error from an OSIS handler used to
surface as -32603 Internal error / "Redis operation error:" because the
generated server glue funnelled all typed errors through
`RpcError::Operation(String)`, discarding the category.

Preserve the category end-to-end:

* `RpcErrorKind` (Invalid / NotFound / PermissionDenied / Internal) +
  matching `RpcError::Invalid`/`NotFound`/`PermissionDenied` variants
  in `crates/osis/src/rpc/error.rs`. Fix the misleading "Redis operation
  error" Display prefix on `RpcError::Operation`.
* Carry `error_kind` on `protocol::RpcResponse` and on the generated
  per-domain `RpcResponse`, so failure data flows with its category.
* Generator emits `category()` on every `<Service>Error` enum and uses
  it in the service-method RPC wrappers; the generated
  `handle_rpc_call` / `handle_service_call` glue reconstructs the right
  typed `RpcError` variant from `error_kind`.
* Dispatch (`crates/osis/src/rpc/dispatch.rs`,
  `crates/server/src/server/{domain,unified}_server.rs`) maps:
    Invalid       → -32602 invalid_params
    NotFound      → -32602 invalid_params
    PermissionDenied → -32000 application_error
    Internal      → -32603 internal_error
  replacing the string-prefix classification.

Acceptance: validation errors now surface as -32602 with a clean
message; real internal faults remain -32603. Behaviour is uniform
across every OSIS service after regeneration (regenerated
example/recipe_server in a follow-up commit).
chore(example): regenerate recipe_server with typed error categories (#83)
Some checks failed
Test / test (push) Failing after 2m14s
b7216e5e3e
Picks up the codegen changes from 7d37514:
- `RecipeServiceError::category()` is now emitted.
- Service RPC wrappers tag `RpcResponse` with `error_kind` from the
  category.
- `handle_rpc_call` / `handle_service_call` reconstruct the typed
  `RpcError` variant (`Invalid` / `NotFound` / `PermissionDenied` /
  `Operation`) instead of funnelling through `RpcError::Operation`.
- CRUD wrappers tag missing-parameter responses as `Invalid` so they
  surface as JSON-RPC -32602 instead of -32603.
test(error-category): cover typed RpcError propagation (#83)
Some checks failed
Test / test (push) Failing after 2m45s
c4f65ce777
* Unit tests in `crates/osis/src/rpc/error.rs` for `RpcError::kind()`
  and the renamed `Operation` Display (no more `Redis operation error:`).
* Unit tests in `crates/osis/src/rpc/dispatch.rs` for the
  `RpcErrorKind` → JSON-RPC code mapping (Invalid → -32602,
  PermissionDenied → -32000, Internal → -32603).
* Integration tests in `example/recipe_server/.../recipes/tests.rs`
  driving `OsisRecipes::handle_service_call` and asserting:
    - missing parameter → `RpcError::Invalid`
    - handler returning `RecipeServiceError::NotFound` →
      `RpcError::NotFound`
    - unknown method body still carries the `Unknown method:` marker
      that dispatch.rs uses to route to `method_not_found`.

These pin the acceptance criteria from the issue: validation errors
surface as -32602 with a clean message (no `Redis operation error:`
prefix), real internal faults still surface as -32603.
test(error-category): move #83 tests to tests_error_category.rs
Some checks failed
Test / test (push) Failing after 2m27s
Test / test (pull_request) Failing after 2m11s
46601e1853
The auto-generated `tests.rs` is rewritten by the build script on
every build, so the integration tests from c4f65ce kept getting
clobbered.

Move them to a sibling `tests_error_category.rs` that mod.rs pulls
in under `#[cfg(test)]`, and fix a longstanding template typo in
`crates/generator/src/generate/tests_emit.rs` (`super::server::*` →
`super::*`) so the auto-generated tests.rs compiles cleanly under
the current nested layout.
timur merged commit ec80c9acec into development 2026-05-20 08:16:42 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
lhumina_code/hero_rpc!86
No description provided.