에러코드를 어떻게 처리할 것인가(UX)

정인우·2022년 12월 1일
0

React Dev.

목록 보기
3/8
post-thumbnail

아무리 잘 작성하더라도 에러는 발생하기 마련입니다. 갑자기 서버에 불이 나버린다던가, 데이터가 날아가는 일이 발생하거나 같은 극단적이 일이 발생한다면 에러는 피할 수 없고, 이러한 극단적인 일이 아니더라도 에러는 충분히 발생할 수 있기에 대비해야 합니다.

또한 에러는 사용자에게 어느 정도의 수준까지는 적절한 통보가 이루어져야 합니다. 만약 내용을 빈 칸으로 입력했을 때 이를 submit 하는 것에 에러가 발생했을 때, 이에 대해 어떠한 알람도 주어지지 않거나 너무 형식적인 에러를 제공시 사용자는 자력으로 문제를 해결할 수 없습니다.

예를 들어, 위의 문제에서 에러 알람이 그저 문제가 있습니다라고 한다면, 사용자는 아래의 다양한 원인 속에서 고민을 해야 합니다.

  1. 어플리케이션의 서버가 이상하다
  2. 사용자 본인의 네트워크 이상
  3. 필수 정보가 누락되었다.
  4. 로그인 정보가 만료되었다
  5. 제출 가능 기간이 지났다
  6. 또는 기타 특수 조건이 부합하지 않는다.

이러한 일을 피하기 위해서는 사용자가 스스로 문제를 해결할 수 있거나 또는 사용자가 스스로 해결 불가능한 문제에 시간을 투자하지 않게끔 하기 위한 알림이 필요합니다. 이를 위해서 해당 프로젝트에서는 react-toastify를 활용한 간단한 토스트 알람 푸쉬 함수를 작성하였습니다. 해당 함수는 다음 링크()에서 확인할 수 있습니다.

그리고 이러한 다양한 에러를 어디에서 처리할 것인지에 대해서 고민을 하였습니다.

  1. axios interceptor
  2. 각 api 호출부 chain

기본적으로 1에서 처리를 진행하려고 했으나 링크() 에서 처럼 axios interceptor를 이미 token refresh, add, validate를 위해서 로직을 구성하여 사용하여서 해당 부분에 추가하는 것이 일관성에 좋지 않다라는 생각이 들었습니다.

또한 이전에 해당 부분에서 처리했을 때, 다양한 api 콜들이 추가될 때 마다 그에 따른 에러 코드가 추가되고 점점 비대해지는 interceptor error handling part 때문에 보기 좋다고 생각되지 않았습니다. api 별로 각각 가진 에러코드를 해당 api에서 사용에서 같이 다루어주는 것이 좋다라고 생각하여 2를 선택하였으나, 그렇다고 1과 너무 멀어지면 안된다고 생각하였습니다.

api 부분에 error code config를 작성하여 일원화하여 관리하였고 추가적으로, 이를 toast 알림을 쏴주는 것까지 한 번에 연결하였습니다.

import { pushNotification } from '@/util/notification';

type ErrorConfig = { message: string };

const errorConfig: Record<string, ErrorConfig> = {
  // Common
  C01: {
    message: '잘못된 입력값입니다',
  },
  C02: {
    message: '잘못된 입력값입니다',
  },
  C03: {
    message: '해당 객체를 찾을 수 없습니다',
  },
  C04: {
    message: '서버에 문제가 발생했습니다',
  },
  C05: {
    message: '잘못된 타입의 값입니다',
  },

  //User
  ... 생략
  
  //User-Token
  ... 생략

  //Video
  ... 생략

  //Individual Video
  ... 생략

  //Video Space
  ... 생략

  //External API
  E01: {
    message: '외부 서비스 호출에 실패했습니다',
  },
};

export const getErrorToast = (errorCode: string): void => {
  const error = errorConfig[errorCode];

  if (!error) {
    return pushNotification('알 수 없는 에러가 발생했습니다', 'error');
  }
  return pushNotification(error.message, 'error');
};

해당 함수에 에러 코드에 대한 것을 일원화하여 관리하였고 api 호출 시에 반환되는 code 값을 해당 함수에 보내주는 것으로 간단화 시켰습니다. 현재로서는 에러 코드에 대한 메시지만을 요구하는 일은 없기에 toast 알림을 진행하는 함수에 대해서만 export 했습니다.

사용 예시

const initialize = useCallback(async () => {
    const { status, data, code } = await getHostedVideoList();
    if (status === 200) {
      setVideoSpaceData(data);
    } else {
      getErrorToast(code);
    }
  }, []);

useLayoutEffect(() => {
   initialize();
}, [initialize]);

api 콜을 진행하면서 error code 및 처리를 getErrorToast에서 진행하기에 code에 대해서 추가적인 처리를 해줄 것이 없고 해당 부분을 작성하는 개발자 역시 이를 신경쓰지 않아도 됩니다.

에러 코드 같은 경우에 분야별 주석을 달아 처리하기 편하게 하고자 했습니다.

해당 코드를 통해 관심사의 분리를 어느 정도 이끌어냈다고 생각합니다만 더 좋은 코드나 지적이 있다면 언제든 부탁드립니다. 감사합니다.

0개의 댓글