IT/기초 지식

[axios] axios의 error handling

개발자 두더지 2023. 6. 10. 21:38
728x90

일본의 한 블로그 글을 번역한 포스트입니다. 오역 및 의역, 직역이 있을 수 있으며 틀린 내용은 지적해주시면 감사하겠습니다.

 

 

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

728x90