Errors
// How errors surface
Every API call either resolves with the typed body or throws an ApiError. UI code catches that error, shows a Sonner toast with the message, and falls back to a default mapping for status codes the backend did not annotate. The dashboard also has framework-level fallbacks:
- 404
app/not-found.tsx— friendly message with a link home, served on unknown routes. - ERR
app/error.tsx— segment-level error boundary; shown when a page throws during render. - FATAL
app/global-error.tsx— top-level safety net for errors that crash the root layout. - LOAD
app/loading.tsx— global suspense fallback shown while a route is fetching.
// Default messages
When the backend does not provide a message, the API client uses these defaults:
- 401"You are signed out. Please log in again." (also forces sign-out)
- 403"You don't have permission to do that."
- 404"Not found."
- 429"Too many requests. Please slow down."
- 5xx"The server had a hiccup. Please try again."
// Custom backend messages
When the backend returns { "error": "..." } or { "message": "..." }, that string is shown verbatim. Backend authors should prefer human-readable, action-oriented messages — the dashboard surfaces them directly to the user.