Skip to content

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 CodeMeaningHandling Strategy
400Bad RequestDisplay the server response validation message to the user
401Authentication FailedAttempt token refresh. Redirect to the login page on refresh failure
403ForbiddenDisplay an insufficient access permissions message
404Not FoundInform the user that the requested data could not be found
409ConflictInform the user of the data conflict and prompt a refresh
422Unprocessable EntityMap server validation failure messages to form fields
500Server ErrorDisplay a generic server error message. Do not expose details
502/503Service UnavailableDisplay a maintenance or temporary error notice

14.3.2. Network Errors

  • When no server response is received (error.response is undefined), 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.onLine property and online/offline event 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 AppError class 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 handleApiError to transform errors.
  • When common handling is required, transformation should be performed in the response interceptor.

TIENIPIA QUALIFIED STANDARD