import * as m from '$lib/paraglide/messages.js'; /** * Mirror of the backend ErrorCode enum. * Keep in sync with backend/src/main/java/org/raddatz/familienarchiv/exception/ErrorCode.java */ export type ErrorCode = | 'DOCUMENT_NOT_FOUND' | 'DOCUMENT_NO_FILE' | 'FILE_NOT_FOUND' | 'FILE_UPLOAD_FAILED' | 'UNSUPPORTED_FILE_TYPE' | 'USER_NOT_FOUND' | 'EMAIL_ALREADY_IN_USE' | 'WRONG_CURRENT_PASSWORD' | 'IMPORT_ALREADY_RUNNING' | 'INVALID_RESET_TOKEN' | 'ANNOTATION_NOT_FOUND' | 'ANNOTATION_OVERLAP' | 'COMMENT_NOT_FOUND' | 'UNAUTHORIZED' | 'FORBIDDEN' | 'VALIDATION_ERROR' | 'INTERNAL_ERROR'; export interface BackendError { code: ErrorCode; message: string; // English developer message — not shown to users } /** * Attempts to parse a backend ErrorResponse from a failed fetch response. * Returns null if the body is not valid JSON or does not contain a code field. */ export async function parseBackendError(res: Response): Promise { try { const body = await res.json(); if (body && typeof body.code === 'string') { return body as BackendError; } } catch { // Body was not JSON } return null; } /** Returns a localised message for the given error code via Paraglide. Falls back to INTERNAL_ERROR. */ export function getErrorMessage(code: ErrorCode | string | undefined): string { switch (code) { case 'DOCUMENT_NOT_FOUND': return m.error_document_not_found(); case 'DOCUMENT_NO_FILE': return m.error_document_no_file(); case 'FILE_NOT_FOUND': return m.error_file_not_found(); case 'FILE_UPLOAD_FAILED': return m.error_file_upload_failed(); case 'UNSUPPORTED_FILE_TYPE': return m.error_unsupported_file_type(); case 'USER_NOT_FOUND': return m.error_user_not_found(); case 'EMAIL_ALREADY_IN_USE': return m.error_email_already_in_use(); case 'WRONG_CURRENT_PASSWORD': return m.error_wrong_current_password(); case 'IMPORT_ALREADY_RUNNING': return m.error_import_already_running(); case 'INVALID_RESET_TOKEN': return m.error_invalid_reset_token(); case 'ANNOTATION_NOT_FOUND': return m.error_annotation_not_found(); case 'ANNOTATION_OVERLAP': return m.error_annotation_overlap(); case 'COMMENT_NOT_FOUND': return m.error_comment_not_found(); case 'UNAUTHORIZED': return m.error_unauthorized(); case 'FORBIDDEN': return m.error_forbidden(); case 'VALIDATION_ERROR': return m.error_validation_error(); default: return m.error_internal_error(); } }