feat: carry validation field errors in AppError

This commit is contained in:
CREDO23 2026-07-23 18:52:50 +02:00
parent 6330d5a789
commit 18f5d30e61
2 changed files with 17 additions and 2 deletions

View file

@ -10,6 +10,7 @@ import {
AuthorizationError, AuthorizationError,
NetworkError, NetworkError,
NotFoundError, NotFoundError,
type ValidationFieldError,
} from "../error"; } from "../error";
enum ResponseType { enum ResponseType {
@ -165,6 +166,9 @@ class BaseApiService {
const requestId: string | undefined = const requestId: string | undefined =
envelope?.request_id ?? response.headers.get("X-Request-ID") ?? undefined; envelope?.request_id ?? response.headers.get("X-Request-ID") ?? undefined;
const reportUrl: string | undefined = envelope?.report_url; const reportUrl: string | undefined = envelope?.report_url;
const validationFields: ValidationFieldError[] | undefined = Array.isArray(envelope?.fields)
? envelope.fields
: undefined;
// Handle 401 - try to refresh token first (only once) // Handle 401 - try to refresh token first (only once)
if (response.status === 401) { if (response.status === 401) {
@ -209,8 +213,8 @@ class BaseApiService {
response.status, response.status,
response.statusText response.statusText
); );
default: default: {
throw new AppError( const appError = new AppError(
errorMessage || "Something went wrong", errorMessage || "Something went wrong",
response.status, response.status,
response.statusText, response.statusText,
@ -218,6 +222,9 @@ class BaseApiService {
requestId, requestId,
reportUrl reportUrl
); );
appError.fields = validationFields;
throw appError;
}
} }
} }
refreshRetryBlockedUntil.delete(getRefreshRetryKey(mergedOptions.method, url)); refreshRetryBlockedUntil.delete(getRefreshRetryKey(mergedOptions.method, url));

View file

@ -1,11 +1,19 @@
export const SURFSENSE_ISSUES_URL = "https://github.com/MODSetter/SurfSense/issues"; export const SURFSENSE_ISSUES_URL = "https://github.com/MODSetter/SurfSense/issues";
/** One field-level failure from a 422 validation response. */
export interface ValidationFieldError {
loc: string[];
msg: string;
}
export class AppError extends Error { export class AppError extends Error {
status?: number; status?: number;
statusText?: string; statusText?: string;
code?: string; code?: string;
requestId?: string; requestId?: string;
reportUrl?: string; reportUrl?: string;
/** Per-field failures from a 422 response, keyed by their location path. */
fields?: ValidationFieldError[];
constructor( constructor(
message: string, message: string,
status?: number, status?: number,