fix(api,web): corrections auth — gestion d'erreur login, messages explicites

- web: auth/errors (+ tests), LoginPage, client API
- api: auth controller/service

Refs: #14
This commit is contained in:
Git Agent
2026-08-23 11:10:08 +02:00
parent 8f7555cfe4
commit 0af88a63ca
6 changed files with 74 additions and 8 deletions

View File

@ -30,10 +30,32 @@ export class ApiFallbackError extends Error {
}
}
export class ApiHttpError extends Error {
constructor(
public readonly status: number,
message: string
) {
super(message);
}
}
export function getApiFallback<T>(error: unknown): T | undefined {
return error instanceof ApiFallbackError ? (error.fallback as T) : undefined;
}
function apiErrorMessage(detail: string, fallback: string): string {
if (!detail) return fallback;
try {
const parsed = JSON.parse(detail) as { message?: unknown; error?: unknown };
if (typeof parsed.message === "string") return parsed.message;
if (Array.isArray(parsed.message)) return parsed.message.join(", ");
if (typeof parsed.error === "string") return parsed.error;
} catch {
return detail;
}
return fallback;
}
async function request<T>(path: string, options: RequestOptions = {}): Promise<T> {
try {
const response = await fetch(`${API_BASE}${path}`, {
@ -50,7 +72,7 @@ async function request<T>(path: string, options: RequestOptions = {}): Promise<T
window.dispatchEvent(new CustomEvent("readabook:session-expired"));
}
const detail = await response.text();
throw new Error(detail || `${response.status} ${response.statusText}`);
throw new ApiHttpError(response.status, apiErrorMessage(detail, `${response.status} ${response.statusText}`));
}
return (await response.json()) as T;