Fix error propagation: surface API validation messages in the UI #29

Merged
gelu merged 1 commits from fix/error-propagation-28 into main 2026-05-28 06:43:25 +00:00
Owner

What

Surface upstream API validation messages in the browser instead of swallowing them in generic fallbacks.

Why

When cv-matcher-api rejects a job URL or file with an actionable 4xx message (e.g. "Only PDF files are supported", "Could not extract enough job text"), the browser was showing a hardcoded fallback string. Users had no idea what went wrong or how to fix it. This wires up the full error path from server business rules to the UI.

Changes

  • startup-helpers/StartupExtensions.csUseJsonExceptionHandler now maps InvalidOperationException → 400 Bad Request (was incorrectly promoted to 500); all other unhandled exceptions remain 500
  • api/Controllers/CvMatcherController.cs — catches Refit.ApiException with status < 500 and forwards the upstream ErrorResponse body (with its human-readable Error message) instead of returning a generic 502
  • common/Responses/ErrorResponse.cs — removed stray Score property; captcha score moved to Detail
  • web/wwwroot/js/main.js — added extractApiError(body, status, fallbackKey, rateLimitKey) helper; updated all four failure handlers (CV upload fetch, CV match fetch, contact form .fail(), subscribe form .fail()) to read the server error body and display it for 4xx, falling back to the i18n string only for 5xx or unparseable responses

Testing

  • No automated tests changed (no test projects in this repo yet)
  • Manual: upload a non-PDF → expect the server's "Only PDF files are supported" message to appear in the UI
  • Manual: contact/subscribe form errors → specific server validation messages shown; rate-limit uses warning tone
  • Manual: 5xx errors continue to show generic i18n fallback (not raw server internals)
  • Build: dotnet build myAi.sln → 0 errors, 0 warnings

Risk Assessment

Checklist

  • All tests passing
  • Code review ready
  • No merge conflicts
## What Surface upstream API validation messages in the browser instead of swallowing them in generic fallbacks. ## Why When cv-matcher-api rejects a job URL or file with an actionable 4xx message (e.g. "Only PDF files are supported", "Could not extract enough job text"), the browser was showing a hardcoded fallback string. Users had no idea what went wrong or how to fix it. This wires up the full error path from server business rules to the UI. ## Changes - `startup-helpers/StartupExtensions.cs` — `UseJsonExceptionHandler` now maps `InvalidOperationException` → 400 Bad Request (was incorrectly promoted to 500); all other unhandled exceptions remain 500 - `api/Controllers/CvMatcherController.cs` — catches `Refit.ApiException` with status < 500 and forwards the upstream `ErrorResponse` body (with its human-readable `Error` message) instead of returning a generic 502 - `common/Responses/ErrorResponse.cs` — removed stray `Score` property; captcha score moved to `Detail` - `web/wwwroot/js/main.js` — added `extractApiError(body, status, fallbackKey, rateLimitKey)` helper; updated all four failure handlers (CV upload fetch, CV match fetch, contact form `.fail()`, subscribe form `.fail()`) to read the server error body and display it for 4xx, falling back to the i18n string only for 5xx or unparseable responses ## Testing - No automated tests changed (no test projects in this repo yet) - Manual: upload a non-PDF → expect the server's "Only PDF files are supported" message to appear in the UI - Manual: contact/subscribe form errors → specific server validation messages shown; rate-limit uses warning tone - Manual: 5xx errors continue to show generic i18n fallback (not raw server internals) - Build: `dotnet build myAi.sln` → 0 errors, 0 warnings ## Risk Assessment - Breaking changes? No — additive only; error messages improve, none removed - Performance impact? None - Closes #28 ## Checklist - [x] All tests passing - [x] Code review ready - [x] No merge conflicts
gelu added 1 commit 2026-05-28 06:41:50 +00:00
- UseJsonExceptionHandler now maps InvalidOperationException to 400 (was 500),
  so upstream business-rule rejections reach the browser as actionable messages.
- CvMatcherController forwards Refit 4xx bodies from cv-matcher-api instead
  of swallowing them in a generic 502.
- ErrorResponse.Score removed; CaptchaController puts the score in Detail.
- Frontend extractApiError helper reads the server Error/error/title field for
  4xx responses and falls back to a generic i18n string for 5xx / missing body.
- All four failure handlers (CV upload, CV match, contact form, subscribe form)
  updated to use extractApiError with the correct rate-limit i18n key.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
claude approved these changes 2026-05-28 06:43:02 +00:00
gelu merged commit 323e41e024 into main 2026-05-28 06:43:25 +00:00
Sign in to join this conversation.
No Reviewers
No Label
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: AI/myAi#29