Fix error propagation: surface API validation messages in the UI

- 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>
This commit is contained in:
2026-05-28 09:41:24 +03:00
parent 2e1efc598b
commit 7908dad181
5 changed files with 80 additions and 15 deletions
+8 -1
View File
@@ -1,9 +1,16 @@
namespace Common.Responses;
/// <summary>
/// Standard error body returned by all API endpoints on 4xx and 5xx responses.
/// </summary>
public sealed class ErrorResponse
{
/// <summary>Human-readable error message, safe to display directly to the end user for 4xx responses.</summary>
public string Error { get; init; } = string.Empty;
/// <summary>Machine-readable error code for programmatic handling (e.g. <c>"captcha_verification_failed"</c>).</summary>
public string? Code { get; init; }
/// <summary>Optional additional detail for debugging (not shown in UI).</summary>
public string? Detail { get; init; }
public double? Score { get; init; }
}