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,
NetworkError,
NotFoundError,
type ValidationFieldError,
} from "../error";
enum ResponseType {
@ -165,6 +166,9 @@ class BaseApiService {
const requestId: string | undefined =
envelope?.request_id ?? response.headers.get("X-Request-ID") ?? undefined;
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)
if (response.status === 401) {
@ -209,8 +213,8 @@ class BaseApiService {
response.status,
response.statusText
);
default:
throw new AppError(
default: {
const appError = new AppError(
errorMessage || "Something went wrong",
response.status,
response.statusText,
@ -218,6 +222,9 @@ class BaseApiService {
requestId,
reportUrl
);
appError.fields = validationFields;
throw appError;
}
}
}
refreshRetryBlockedUntil.delete(getRefreshRetryKey(mergedOptions.method, url));

View file

@ -1,11 +1,19 @@
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 {
status?: number;
statusText?: string;
code?: string;
requestId?: string;
reportUrl?: string;
/** Per-field failures from a 422 response, keyed by their location path. */
fields?: ValidationFieldError[];
constructor(
message: string,
status?: number,