fix(forms): surface server field validation errors in shared fetch hook #201
Loading…
Reference in a new issue
No description provided.
Delete branch "fix/MAPPS-210-surface-server-validation-errors"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
The shared fetch hook collapsed every non-2xx response into "Request failed with status: N" and discarded the backend's validation envelope, so a too-long ticket title (422 with errors[].field = "title") only ever showed an opaque status banner and the offending field was never flagged.
Carry the envelope through the typed error layer: ApiError::Status now holds the parsed errors[] (field / message / code), handle_response and the delete path deserialize them, and ApiError gains field_errors() / field_message(field) accessors plus a 422 user_message() that lists the field messages instead of the generic envelope text.
Route the parsed messages in forms: the ticket create form and the asset create form switch to the *_typed helpers, send a server-flagged field message to the matching input's error slot (Title, Name), and fall back to user_message() when no field envelope is present. Add a maxlength prop to the Input component and cap ticket Title at 500 client-side; the server stays the source of truth.
#MAPPS-210
Co-Authored-By: Claude Opus 4.8 (1M context) noreply@anthropic.com
The MAPPS-210 typed layer carried the validation envelope only for callers that switched to the `_typed` helpers (tickets, assets). The ~40 other create/edit forms still call the `String`-returning helpers (`get`/`post`/`put`/`delete` with/without auth), every one of which collapsed a non-2xx into the bare `Request failed with status: N` and threw the body away, so those forms kept showing the opaque status banner. Add a shared `status_error()` that parses the standard `{"error":{"message","errors":[]}}` envelope and returns the real message (joining the field-level `errors[]` on a 422, e.g. "Name must be between 1 and 255 characters"), falling back to the status line when the body is not a recognised envelope. Route all seven non-2xx branches through it. No call-site changes: every existing form that renders its `String` error now shows the actionable server message instead of the status code, while the `_typed` helpers keep routing field errors next to the offending input. #MAPPS-210