Error Handling
14.3.1. Handling by HTTP Status Code
- API response errors must be classified and handled based on HTTP status codes.
- A handling strategy for each status code must be defined in advance and applied consistently.
| Status Code | Meaning | Handling Strategy |
|---|---|---|
| 400 | Bad Request | Display the server response validation message to the user |
| 401 | Authentication Failed | Attempt token refresh. Redirect to the login page on refresh failure |
| 403 | Forbidden | Display an insufficient access permissions message |
| 404 | Not Found | Inform the user that the requested data could not be found |
| 409 | Conflict | Inform the user of the data conflict and prompt a refresh |
| 422 | Unprocessable Entity | Map server validation failure messages to form fields |
| 500 | Server Error | Display a generic server error message. Do not expose details |
| 502/503 | Service Unavailable | Display a maintenance or temporary error notice |
14.3.2. Network Errors
- When no server response is received (
error.responseisundefined), the error must be classified as a network error. - Network errors and timeout errors must be handled separately.
typescript
// src/api/utils/error.ts
import type { AxiosError } from 'axios'
export function isNetworkError(error: AxiosError): boolean {
return !error.response && error.code !== 'ECONNABORTED'
}
export function isTimeoutError(error: AxiosError): boolean {
return error.code === 'ECONNABORTED'
}- Offline state detection should utilize the
navigator.onLineproperty andonline/offlineevent listeners. - This should be implemented as a composable function (
useNetworkStatus) for reactive usage within components.
14.3.3. User Feedback
- Appropriate feedback must be provided to the user when an API error occurs.
- Error messages must be managed in a standardized format.
typescript
// src/api/utils/notify.ts
const ERROR_MESSAGES: Record<string, string> = {
NETWORK_ERROR: 'Please check your network connection.',
TIMEOUT_ERROR: 'The request has timed out. Please try again.',
UNAUTHORIZED: 'Your session has expired. Please log in again.',
FORBIDDEN: 'You do not have access permissions.',
NOT_FOUND: 'The requested data could not be found.',
SERVER_ERROR: 'A server error occurred. Please try again later.',
DEFAULT: 'An error occurred.',
}
export function getErrorMessage(code: string): string {
return ERROR_MESSAGES[code] ?? ERROR_MESSAGES.DEFAULT
}- If an error message is provided by the server, that message should be used preferentially.
- If no server message is available or the message contains technical details, it must be replaced with a standard message.
14.3.4. Global Error Handler
- A handler must be implemented to transform Axios errors into application-standard error objects.
- An
AppErrorclass must be defined to unify error types.
typescript
// src/api/errors/AppError.ts
export class AppError extends Error {
readonly status: number
readonly code: string
constructor(status: number, code: string, message: string) {
super(message)
this.name = 'AppError'
this.status = status
this.code = code
}
}typescript
// src/api/errors/handleApiError.ts
import type { AxiosError } from 'axios'
import { AppError } from './AppError'
import { isNetworkError, isTimeoutError } from '@/api/utils/error'
export function handleApiError(error: AxiosError): AppError {
if (isTimeoutError(error)) {
return new AppError(0, 'TIMEOUT_ERROR', 'Request timed out')
}
if (isNetworkError(error)) {
return new AppError(0, 'NETWORK_ERROR', 'Network error')
}
const status = error.response?.status ?? 0
const data = error.response?.data as Record<string, string> | undefined
return new AppError(status, data?.code ?? 'UNKNOWN_ERROR', data?.message ?? 'Unknown error')
}- Individual API calls should use
handleApiErrorto transform errors. - When common handling is required, transformation should be performed in the response interceptor.