TypeScript에서 axios error 핸들링하기

yes·2023년 3월 31일
19

catch문에서 error 타입

try {
  // try 부분
} catch(error) { // error type is unkown
  // catch 부분
}

tsc v4.4부터, try...catch에서 catch의 error object의 타입정의가 변경되었다.

기존에는 error type이 any였지만, tsc4,4부터 error type이 unkown으로 변경되었다.

우선 anyunkonw type의 차이점을 살펴보자.

TypeScript에서 any는 모든 타입을 할당받을 수 있는 타입이다. 즉 any 타입으로 선언된 변수, argument는 모든 타입의 값이 할당될 수 있고 전달될 수 있는 것이다.
unknown 타입도 any과 마찬가지로 모든 타입의 값이 할당될 수 있다.
하지만 조금 다른 것은 unknown 타입으로 선언된 변수는 any를 제외한 다른 타입으로 선언된 변수에 할당될 수 없다는 것이다.
unknown 타입의 특징은 한 가지 더 있는데, unknown 타입으로 선언된 변수는 프로퍼티에 접근할 수 없으며, 메소드를 호출할 수 없으며, 인스턴스를 생성할 수도 없다. 알려지지 않은 타입이라 그런 것이다.

isAxiosError

앞서 살펴보았듯이, 우리는 catch문의 error type이 unkown이라는 것을 알게되었다.
따라서 우리는 이 error가 어떤 error인지 알지 못한다.
axios에서는 isAxiosError라는 메서드가 존재한다. 이 메서드는 주어진 인자가 axios에서 발생한 error인지 판별하는 역할을 한다.

try {
  const response = axios.get(url)
} catch(error) {
  if (axios.isAxiosError(error) {
    // axios에서 발생한 error
  }
}

isAxiosError의 type을 살펴보면
단, 여기서 type이 axios의 버전에 따라서 달라지기 때문에 알아보아야합니다.변경 사항 github
여기서는 구 버전으로 설명을 하겠습니다.
구 버전,

isAxiosError(payload: any): payload is AxiosError;

최근 버전,

isAxiosError<T = any, D = any>(payload: any): payload is AxiosError<T, D>;

이렇게 되어있다.
따라서, isAxiosError를 사용하여 검사하고 참이 되면 들어오는 if문 안에 error의 type은 AxiosError로 된다.

Axios error response data type 정하기

우선, Axios에서 어떻게 type이 지정되어있는지 살펴보아야 합니다.

interface AxiosError<T = any, D = any> extends Error {
  config: AxiosRequestConfig<D>;
  code?: string;
  request?: any;
  response?: AxiosResponse<T, D>;
  isAxiosError: boolean;
  toJSON: () => object;
}
interface AxiosResponse<T = any, D = any>  {
  data: T;
  status: number;
  statusText: string;
  headers: AxiosResponseHeaders;
  config: AxiosRequestConfig<D>;
  request?: any;
}

최근 버전에서는 이제 설명하는 것처럼 할 필요 없이 isAxiosError를 사용할 때 제네릭으로 type을 받기 때문에 바로 넣어주면 됩니다.
예시) ResponseDataType

try {
  const response = axios.get(url)
} catch(error) {
  if (axios.isAxiosError<ResponseDataType, any>(error) {
    // axios에서 발생한 error
  }
}

최근 버전이 아니라면 따로 resonse data의 type을 제네릭으로 받아주지 않기 때문에 함수를 하나 만들어야 합니다.

 const isAxiosError = <ResponseDataType>(
    error: unknown,
  ): error is AxiosError<ResponseDataType> => {
    return axios.isAxiosError(error);
  };

이처럼 제네릭으로 type을 받아서 AxiosError의 제네릭으로 전달해주는 함수를 만들어야 합니다.
이렇게 되면 ResponseDataType의 type으로 response data의 type이 지정되게 됩니다.

interface ResponseDataType {
  message: string;
  code: number;
}

try {
  const response = axios.get(url)
} catch(error) {
  if (isAxiosError<ResponseDataType>(error) {
    error.response?.data.message;
    error.response?.data.code;
  }
}

마침

axios 에러에 대해서 공통적으로 처리하려다가 마주친 문제를 해결하고 axios의 라이브러리 코드를 자세히 살펴보면서 type에 대해서 파헤칠 수 있는 기회가 되었습니다. 추가로 제네릭과 unkown의 type, unkownany의 차이에 대해서 명확하게 알 수 있었습니다.

0개의 댓글