/* ============================================================ errors.js — the API error type and FastAPI `detail` unwrapping. Lifted verbatim from the original src/api.js. FastAPI returns errors as {detail: ...} where `detail` is a string for HTTPException and an array of {loc, msg, type} objects for request-validation failures — parseDetail already handles both shapes, so it moves unchanged. ============================================================ */ export class ApiError extends Error { constructor(message, status, body) { super(message) this.name = 'ApiError' this.status = status this.body = body } } /** Raised when the refresh token itself is rejected — the session is over. */ export class SessionExpiredError extends Error { constructor(message = 'Your session has expired. Please sign in again.') { super(message) this.name = 'SessionExpiredError' } } export function parseDetail(detail) { if (detail == null || detail === '') return null if (typeof detail === 'string') return detail if (Array.isArray(detail)) { return detail .map((item) => { if (typeof item === 'string') return item if (item && typeof item === 'object') { return item.msg || item.message || JSON.stringify(item) } return String(item) }) .filter(Boolean) .join('; ') } if (typeof detail === 'object') { return detail.msg || detail.message || JSON.stringify(detail) } return String(detail) } export function friendlyAuthError(err, fallback = 'Something went wrong. Please try again.') { if (!(err instanceof ApiError)) { return err?.message || fallback } const fromServer = parseDetail(err.body?.detail) switch (err.status) { case 429: return fromServer || 'Too many attempts. Please wait a moment and try again.' case 404: return fromServer || 'No account found for that email.' case 400: return fromServer || 'Please check your details and try again.' case 401: return fromServer || 'Incorrect email or password.' case 403: return fromServer || 'Your Approval is at Pending' case 409: return fromServer || 'An account with that email already exists.' case 502: return fromServer || 'Email service is temporarily unavailable. Please try again later.' default: return fromServer || err.message || fallback } }