개발잡학지식

Axios Interceptors로 내가 원하는 에러 처리 하기

개형이 2023. 8. 10. 10:40

 

현재 내가 투입된 프로젝트에는 Axios를 사용하고 있었고

 

Axios Instance의 Interceptors를 사용하여 에러 처리를 하고 있었다.

 

그런데 나는 특정 에러를 받았을 때 화면에 기존 에러가 발생했을 때와 다른 팝업을 띄우고 싶었는데,

 

현재 짜여진 코드 상으로는 그게 불가능했다... (모든 에러는 같은 식으로 처리됐다)

 

그래서 특정 에러 발생에 대한 처리를 추가해주는 코드를 Interceptors에 추가해보기로 했다!

 

 


 

 

1. 현재 코드 구조

 

// Api 호출 함수
static async getApi(requestParameters: requestType): Promise<responseType> {
    const requestConfig: AxiosRequestConfig = {
      url: '/~~~',
      method: 'GET',
      params: requestParameters,
    } as AxiosRequestConfig

    const {data} = await ApiFactoryInstance.get().request<responseType, AxiosResponse<responseType>>(requestConfig)

    return data
}

 

위 코드는 Api 호출을 담당하는 함수다.

내부를 보면 ApiFactoryInstance.get().request 코드가 무엇을 수행하는지 알아야 할 것 같다. 타고 가보자.

 

 

export class ApiFactory {

  private axiosInterceptor: AxiosInterceptor
  private axiosInstance: AxiosInstance

  constructor(token: string = '') {
    this.axiosInterceptor = new AxiosInterceptor(token)
    this.axiosInstance = this.axiosInterceptor.getClient()
  }

  get() {
    return this.axiosInstance
  }
  
  // ...
}

const ApiFactoryInstance = new ApiFactory()

 

위 클래스의 get() 메소드가 api 호출에 관여하는 것 같다.

constructor에서 보면 프로젝트 내에서 직접 만든 AxiosInterceptor가 Api를 호출할 때마다 무조건 동작된다는 것을 알 수 있다.

그러면 AxiosInterceptor의 코드를 한번 살펴보자.

 

 

export interface AxiosErrorType extends InternalAxiosRequestConfig {
  // ...
}
export default class AxiosInterceptor {
  // ...

  constructor (token: string = '') {
  	// ...
    this.instance.interceptors.response.use(
    	this.responseInterceptor.bind(this)
    	, this.responseErrorInterceptor.bind(this))
    // ...
  }
  responseErrorInterceptor(error: AxiosErrorType) {
    if (error) {
      if (error.~~~) {
        // 에러 처리가 여기서 진행되고 있었다.
      } else {
        return // ...
      }
    } else {
      // ...
      return // ...
    }
  }
 }

 

AxiosInterceptor의 코드를 보니 에러가 일괄로 처리되는 ErrorInterceptor가 response에 따라 항상 진입된다는 것을 알 수 있었다.

그래서 내가 생각한 방법은 위 코드의 responseErrorInterceptor새로운 조건문을 Guard Clause로 추가하여,

특정 에러 발생 시에 하단 일괄적으로 처리되는 코드를 타지않고 바로 리턴해버리는 것이다.

 

 

 

 

2. 작업 실행

 

우선 1번의 AxiosInterceptor 코드에서 AxiosErrorType에 새로운 타입을 추가해보자.

 

export interface AxiosErrorType extends InternalAxiosRequestConfig {
  // ...
  handleError?: (error) => boolean
}

 

AxiosInterceptor 내에서는 true or false로만 결과를 받아 참일 경우에만 일괄 에러 처리 코드를 안타게 작업해줄 것이다.

그래서 return boolean으로 처리했고, 특정 에러에 대한 처리는 Api 호출 코드에 넣을 것이다.

 

타입을 추가했으니 responseErrorInterceptor에 특정에러처리 코드를 추가해보자.

 

 

responseErrorInterceptor(error: AxiosErrorType) {
    
    // handleError를 받았을 경우에만 아래 코드가 실행되고 곧바로 리턴된다.
    if (error.config['handleError'](error)) {
      return // ...
    }
    
    if (error) {
      if (error.~~~) {
        // 에러 처리가 여기서 진행되고 있었다.
      } else {
        return // ...
      }
    } else {
      // ...
      return // ...
    }
  }

 

 

위 코드를 보면 handleError가 true일 경우에는 일괄에러처리 코드를 타지 않고 바로 Error Interceptor를 빠져나가는 것을 알 수 있다.

그러면 이제 Api 호출하는 부분에서 어떻게 handleError를 넣어줄까?

 

 

// Api 호출 함수
static async getApi(requestParameters: requestType, handleError?: (error) => boolean): Promise<responseType> {
    const requestConfig: AxiosRequestConfig = {
      url: '/~~~',
      method: 'GET',
      params: requestParameters,
      handleError: handleError,
    } as AxiosRequestConfig

    const {data} = await ApiFactoryInstance.get().request<responseType, AxiosResponse<responseType>>(requestConfig)

    return data
}

 

handleError를 파라미터로 받고 같이 넘겨주면 된다.

그러면 위 함수를 호출하는 부분에서 특정 에러를 처리하는 코드를 넣어 직접 처리하고, true or false만 리턴해주도록 할 것이다.

 

 

// Get Api 함수를 호출
const res = await getApi({
	// ...
}, getApiHandleError) // 여기에 파라미터가 추가됐다.

// 에러 처리
const getApiHandleError = (error) => {
    if (error.response.data.errorMessageCd === '처리를 원하는 에러 메시지 코드') {
      // ...
      return true
    } else {
      return false
    }
 }

 

Get Api에 추가된 파라미터에 에러처리하는 함수를 넣어준다.

에러 처리하는 함수에서는 내가 처리를 원하는 특정 에러에 대해서 원하는 동작을 수행한 뒤 true or false만 리턴해준다.

만약 위 결과가 true라면 ErrorInterceptor 코드에서 구멍을 뚫어놓았던 그 조건문이 실행될 것이다.

 

 


 

 

 

Axios Interceptor에서 특정 에러에 대한 처리를 따로 하는 방법에 대해 글을 적어보았다.

너무 두서 없어서 나를 제외한 다른 사람이 이해할 수 있을진 모르겠지만,

피드백은 언제나 환영입니다.