type FetchWithAbortResult =
| { response: Response; abort: () => void }
| { error: NetworkError | HttpError }
class NetworkError extends Error {
constructor(message: string) {
super(message)
this.name = 'NetworkError'
}
}
class HttpError extends Error {
constructor(public status: number, message?: string) {
super(message || `HTTP error: ${status}`)
this.name = 'HttpError'
}
}
async function fetchWithAbortController(
url: string,
options: RequestInit = {}
): Promise<FetchWithAbortResult> {
const controller = new AbortController()
const { signal } = controller
try {
const response = await fetch(url, { ...options, signal })
if (!response.ok) {
throw new HttpError(response.status)
}
return {
response,
abort: () => controller.abort(),
}
} catch (error) {
if (error.name === 'AbortError') {
return {
error: new NetworkError(),
}
}
const e =
error instanceof HttpError ? error : new NetworkError(error.message)
return {
error: e,
}
}
}
- API 요청 시 발생할 수 있는 오류 문제의 필요성
- AbortController 사용과 사용자 정의 에러 클래스를 통한 에러 관리
- HTTP 요청과 네트워크 오류를 안정적으로 처리
#378