diff --git a/frontend/src/api/client.ts b/frontend/src/api/client.ts index 540d69dc..7e5432f0 100644 --- a/frontend/src/api/client.ts +++ b/frontend/src/api/client.ts @@ -25,7 +25,12 @@ function handleGlobalError(error: AxiosError) { } const status = error.response.status - const data = error.response.data as { detail?: string } + const data = error.response.data as { detail?: string | unknown[] } + + // Extract a displayable error message from the response. + // FastAPI returns `detail` as a string for most errors, but 422 validation + // errors return an array of objects — we must not pass those to toast. + const detail = typeof data?.detail === 'string' ? data.detail : undefined // Don't show toast for 401 (handled by refresh interceptor) if (status === 401) { @@ -34,13 +39,13 @@ function handleGlobalError(error: AxiosError) { // Rate limit if (status === 429) { - toast.error(data?.detail || 'Too many requests — please try again shortly') + toast.error(detail || 'Too many requests — please try again shortly') return } // Client errors (4xx) — show backend detail if present if (status >= 400 && status < 500) { - toast.error(data?.detail || 'Invalid request') + toast.error(detail || 'Invalid request') return } diff --git a/frontend/src/store/authStore.ts b/frontend/src/store/authStore.ts index 5053fcbe..e06fbc32 100644 --- a/frontend/src/store/authStore.ts +++ b/frontend/src/store/authStore.ts @@ -48,8 +48,9 @@ export const useAuthStore = create()( // Fetch user info await get().fetchUser() } catch (error: unknown) { - const axiosErr = error as { response?: { data?: { detail?: string } } } - const message = axiosErr.response?.data?.detail || (error instanceof Error ? error.message : 'Login failed') + const axiosErr = error as { response?: { data?: { detail?: unknown } } } + const rawDetail = axiosErr.response?.data?.detail + const message = (typeof rawDetail === 'string' ? rawDetail : null) || (error instanceof Error ? error.message : 'Login failed') set({ error: message, isLoading: false }) throw error } @@ -62,8 +63,9 @@ export const useAuthStore = create()( // After registration, log the user in await get().login({ email: data.email, password: data.password }) } catch (error: unknown) { - const axiosErr = error as { response?: { data?: { detail?: string } } } - const message = axiosErr.response?.data?.detail || (error instanceof Error ? error.message : 'Registration failed') + const axiosErr = error as { response?: { data?: { detail?: unknown } } } + const rawDetail = axiosErr.response?.data?.detail + const message = (typeof rawDetail === 'string' ? rawDetail : null) || (error instanceof Error ? error.message : 'Registration failed') set({ error: message, isLoading: false }) throw error }