bananas-commerce-admin
Version:
What's this, an admin for apes?
76 lines (65 loc) • 2.24 kB
text/typescript
export interface FormErrors {
fieldErrors: Record<string, string>;
formErrors: string[];
}
export class ValidationError extends Error {
fieldErrors: Record<string, string>;
formErrors: string[];
constructor(message: string, errors: FormErrors) {
super(message);
this.name = "ValidationError";
this.fieldErrors = errors.fieldErrors;
this.formErrors = errors.formErrors;
}
}
/**
* Extract form and field level errors from a 400 response, if present.
*/
export async function getFormErrors(response: Response): Promise<FormErrors | null> {
if (response.status < 400 || response.status >= 500) {
return null;
}
const fieldErrors: Record<string, string> = {};
const formErrors: string[] = [];
try {
const payload = await response.clone().json();
const detail = payload?.detail ?? payload;
const appendFormError = (message: unknown) => {
if (message == null) return;
formErrors.push(String(message));
};
const setFieldError = (field: string | undefined, message: unknown) => {
if (!field || field === "__root__") {
appendFormError(message ?? "Invalid input");
return;
}
if (fieldErrors[field] == null && message != null) {
fieldErrors[field] = String(message);
}
};
if (typeof detail === "string") {
appendFormError(detail);
} else if (Array.isArray(detail)) {
for (const error of detail) {
const loc = Array.isArray(error?.loc) ? error.loc : [];
const message =
error?.msg ??
error?.message ??
error?.detail ??
(typeof error === "string" ? error : "Invalid input");
const field = loc.filter((part: unknown) => part !== "body").pop();
setFieldError(typeof field === "string" ? field : undefined, message);
}
} else if (detail && typeof detail === "object") {
for (const [field, message] of Object.entries(detail)) {
setFieldError(field, message);
}
}
} catch (error) {
console.error("[FORM_VALIDATION] Failed to parse form errors", error);
}
if (Object.keys(fieldErrors).length === 0 && formErrors.length === 0) {
return null;
}
return { fieldErrors, formErrors };
}