※ 일본의 한 블로그 글을 번역한 포스트입니다. 오역 및 의역, 직역이 있을 수 있으며 틀린 내용은 지적해주시면 감사하겠습니다.
axios란?
JavaScript(Node.js)의 HTTP 통신에 편리한 라이브러리이다. 상세한 내용은 github를 참고하길 바란다.
aixos의 error handling 이해하기
설명용 소스코드
const express = require('express')
const app = express()
// 생략
app.listen(8081, () => console.log('listening on port 8081!'))
const axios = require('axios').default;
const instance = axios.create({
baseURL: 'https://api.countrystatecity.in/v1/',
timeout: 2000,
headers: { 'X-CSCAPI-KEY': `${process.env.COUNTRYSTATECITY_API_KRY}` }
})
app.get('/allCountries', async (req, res) => {
try {
const countries = await instance.get('countries')
res.send({ countries: countries.data })
} catch (error) {
errorHandler(res, error)
}
})
const errorHandler = (res, error) => {
// 여기를 구현하고 싶은 상태
}
errorHandlier(res, error)의 구현을 하고 싶다고 상정해보자.
axios의 interface을 보고 이해하기
VS code에서 axios의 get을 참조하면 아래의 소스 코드를 볼 수 있다.
export interface AxiosInstance {
// 생략
get<T = any, R = AxiosResponse<T>>(url: string, config?: AxiosRequestConfig): Promise<R>;
// 생략
}
여기에서 HTTP 통신이 성공하면 AxiosResponse 인스턴스(오브젝트)가 반환되어 오는 것을 알 수 있다.
(한편, AxiosResponse는 아래와 같이 정의되어 있으므로, axios.get('/hoge').then((res) => { console.log(res.data) }) 나 axios.get('/hoge').then((res) => { console.log(res.status) })등으로 그 오브젝트, 값을 획득할 수 있다.)
export interface AxiosResponse<T = any> {
data: T;
status: number;
statusText: string;
headers: any;
config: AxiosRequestConfig;
request?: any;
}
그럼 에러가 발생했을 때 어떻게 될까에 대해서 이야기하자면, 에러가 발생했을 때 아래의 AxiosError 인스턴스(오브젝트)가 반환된다.
더욱이 Error 인터페이스를 상속받고 있으며, 이 Error 인터페이스는 다음과 같이 정의되어 있다.
export interface AxiosError<T = any> extends Error {
config: AxiosRequestConfig;
code?: string;
request?: any;
response?: AxiosResponse<T>;
isAxiosError: boolean;
toJSON: () => object;
}
interface Error {
name: string;
message: string;
stack?: string;
}
즉, AxiosError 인터페이스에 엮이는 인스턴스(오브젝트) (실제로는 에러시에 반환되는 오브젝트)에는 다음과 같은 키가 존재한다는 것을 알 수 있다.
- Error : name, message, stack
- AxiosError : config, code, request, response, isAxiosError, toJSON
에러가 발생하는 경우를 나눠서 살펴보기
단순히 에러라고 해도 아래와 같이 두 가지 패턴이 있다고 생각된다.
패턴 | 개요 | 상세 |
1 | response가 있음 (undefined가 아닌) |
API의 request는 유효로 response도 반환되어 왔지만 HTTP status가 200이 아닌 경우 |
2 | response가 undefined | API의 request는 유효이지만, 어떠한 이유로 response가 반환되어 오지 않는 경우 API를 call하려고 했지만 그 전에 에러가 발생한 경우 |
즉, AxiosError의 response가 undefined가 되는지 아닌지 이 두 경우로 나눠서 살펴볼 필요가 있다는 것이다.
그럼 errorHandler(res, error)의 구현은 어떻게 할까?
위에서 언급했던 인터페이스의 정의 +2 패턴이 있는 경우를 바탕으로 이하와 같이 정의하면 모든 에러 패턴에 대응할 수 있다.
const errorHandler = (res, error) => {
if (error.response) {
res.status(error.response.status).send({
error: error.response.data,
errorMsg: error.message
})
} else {
res.status(500).send({ errorMsg: error.message })
}
}
1. AxiosError의 response가 undefined가 아닌 경우, response는 AxiosResponse 인터페이스에 부합하는 오브젝트가 되므로 error.response.data로 Web API에서 반환되어 온 에러 내용을 획득할 수 있다.
또한, AxiosResponse에는 status가 있으므로 이것을 res.status(error.response.status)와 같이 반환하는 것이 가능하다.
2. AxiosError의 response가 undefined인 경우, error.response.hoge는 에러가 되는 대신에 Error인터페이스에서 가지고 있는 message를 이용해 어떤 것이 일어나고 있는지를 파악할 수 있도록 error.messge로 에러 메시지를 획득하고 있다.
참고자료
https://qiita.com/yuta-katayama-23/items/5b8bf72236eec9cadf41
'IT > 기초 지식' 카테고리의 다른 글
DB 설계 공유는 dbdocs를 이용하자 (0) | 2023.06.14 |
---|---|
읽기 쉬운 코드를 쓰기 위한 가이드라인 (0) | 2023.06.11 |
[AWS] SQS의 특징과 SNS와의 차이점 (0) | 2023.05.29 |
[DDD] Entity, ValueObject에 대해서 (0) | 2023.05.26 |
[DDD] 바운디드 컨텍스트(bounded context) - 실전편 (0) | 2023.05.22 |