[Web] Frontend에서의 에러 핸들링

채린·2023년 7월 5일
2

Web

목록 보기
2/2
post-thumbnail

프론트 스터디 주제를 찾아 헤매던 중 .. 이런 동영상을 보게 되었다 !!

https://www.youtube.com/watch?v=FXtooPhupr4

뭐랄까 지금까지 했던 프로젝트에 대한 반성(?) 이 되는 영상이었는데 오늘은 그래서 이 영상에 나온 내용들을 정리하고 나의 경험을 회고하는 식으로 진행해볼까 한다!!


프로젝트를 진행하면서 아마 수많은 에러들과 마주했을 것이라고 생각된다. 일단 Typescript 를 쓰면 늘 마주하는 빨간줄부터 백앤드를 째려보게 되는 500 에러, 갑자기 사용자가 많아지니까 안된다던지 등등 수도 없이 많은 에러와 마주해왔을 것이다..


그렇다면 Hoxy.. 에러예외의 차이를 아시나요?

⭐ 오류(Error) 와 예외(Exception)

프로그래밍에서 오류와 예외의 정의는 다음과 같다.


💗 오류(Error)

하드웨어의 고장 또는 소프트웨어가 본래의 동작을 할 수 없는 상태를 오류라고 한다. 발생하는 시점에 따라 에러를 분류하면 컴파일 에러와 런타임 에러로 나눌 수 있다.


❓ 컴파일 에러(Compile Error) : 코드가 컴파일 될 때 컴파일러가 해석하지 못해서 발생하는 오류

즉, 우리가 Typescript 에서 매번 마주하는 문법 잘못 쓴 건 컴파일 에러에 해당하는 것이다!


❓ 런타임 에러(Runtime Error) : 프로그램이 동작할 때 발견할 수 있는 에러

즉, Try Catch 구문에서 잡히는 에러를 말한다!


물론 Javascript 는 동적 타입의 인터프리터 언어고 Typescript 는 정적 타입의 컴파일 언어이기 때문에 Javascript 는 컴파일 단계가 없이 실행과 동시에 한 줄씩 중간 언어로 해석한 다음 실행하기 때문에 모든 에러가 런타임 환경에서 발생되지만 Typescript는 컴파일 단계에서 SyntaxError or TypeError를 막아준다!! (물론 완벽하게 막아주는 건 아니다..)


우리가 예외 처리할 때를 생각해보면 Try Catch 를 사용해서 error 일 경우에 행해져야 할 행동을 적어두곤 한다. 그러니까 Javascript에서의 예외는 런타임에러라고 생각하면 된다!!

💗 예외(Exception)

런타임 오류와 같은 것을 의미. 예상하기 어렵거나 예상이 불가능한 이슈를 의미


그러니까 우리는 이 예외들을 처리하여 프로그램이 예상치 못하게 종료되거나 제 기능을 못하는 것을 방지해야 한다. 이렇게 예외로 인해 발생한 에러 객체를 핸들링하는 것을 에러핸들링이라고 한다.


그렇다면 우리는 왜 에러핸들링을 해야할까?

⭐ 에러핸들링의 필요성

내가 진행한 프로젝트를 예로 들어서 생각해보면 특화 프로젝트였던 'OMZ'에서 얼굴상을 Tensorflow로 분석해서 해당하는 3D 동물을 리턴하는 식이었는데 예상치 못한 에러가 발생했다.

SignUp

여기서 발생한 두 가지 문제 ! 첫 번째는 분석 되는데 시간이 너무 오래 걸리는데 왜 때문인지 loading 중이 돌아가지 않아 참을성 없는 유저들을 떠나보내게 됐고 두 번째는 사진이 너무 고화질이면 동물상으로 넘어가지 않아 회원가입에서 많은 유저들을 떠나보내게 되었다..


리팩토링을 하면 고쳐야 할 1순위인 이 녀석 .. 예외 처리를 제대로 했다면 수 많은 유저들을 떠나보내지 않았을 것이다..

지금와서 고친다면 가장 먼저 Nginx 상에서 허용되는 파일의 용량을 키워볼 것 같고 거기서도 안 올려지는 사진에 대해서는 try catch 를 이용해서 용량이 너무 크니까 다른 사진을 업로드해주라고 메세지를 띄웠을 것이다 ..!!


즉, 에러핸들링을 이용하여 에러에 대한 인지, 다른 행동을 할 수 있도록 유도하면 서비스에 대한 부정적인 경험을 막을 수 있을 것이다.


다음으로는 에러에는 어떤 것들이 있는 지 알아보자!!

⭐ 에러의 분류

Desktop - 16

에러를 분류하자면 다음과 같다.


💗 예측 가능한 에러

  • 서버 API 로부터 전달받는 에러 중 status 코드가 명확한 에러는 (ex. 401 - 권한이 없는 에러, 403 - 잘못된 접근의 에러) 는 상황에 맞게 에러를 처리할 수 있기 때문에 예측 가능한 에러라고 한다.

💗 예측 불가능한 에러

  • 서버 API로부터 전달받는 에러 중 500대 에러는 예측할 수 없는 에러로 분류한다. 사용자의 네트워크 환경이나 브라우저 환경에서 발생할 수 있는 에러는 예측 불가능한 에러로 분류한다.

💗 해결 가능한 에러

  • 사용자가 에러 상황을 이해해서 해결 가능한 에러를 말한다.
  • 예를 들면, 인증 또는 권한에 대한 에러가 될 수 있다. 예를 들면, 로그인이 되지 않은 사용자가 서비스를 이용하려고 할 때 로그인을 할 수 있도록 로그인 화면을 보여줄 수 있다.
  • 또한, 사용자가 없는 경로로 들어왔을 경우 404 page를 보여줘서 메인으로 돌아가게 할 수 있다.

💗 해결 불가능한 에러

  • 사용자에게 상황을 말해줘도 해결이 불가능한 에러를 말한다.
  • 예를 들면, 저사양 기기 또는 브라우저에서 동작하지 않는 코드가 포함되어 있을 경우, 에러 메세지를 보여줘도 사용자는 할 수 있는 것이 없다.

그렇다면 이러한 에러를 어떻게 핸들링 할 것인가!!!

⭐ 에러핸들링

에러의 분류 그림에서 나누었던 기준으로 에러핸들링을 설명하기 전에 에러핸들링의 기초가 되는 Try Catch 문부터 살펴보자!


Try

  • 에러가 발생할 수도 있는 로직을 작성, 에러가 발생하면 에러객체(name, message 프로퍼티가 존재)를 Catch로 Throw 함

Catch

  • 만약 에러가 발생했다면 Catch 가 받음

Finally

  • 로직의 성공 & 실패 여부와 상관없이 실행해야 하는 부분이 있다면 finally 를 사용하면 무조건 실행되게 됨
const crewNickname = "채린"; 

openFrontFrincess();
try {
    loveFrontFrincess(crewNickname); 
} catch (error) {
    console.error("당신은 공주가 아닙니다."); 
} finally {
    closeFrontFrincess(); 
}

대충 작성해보면 이런 식으로 작성하면 되는데 .. 나 같은 경우는 프로젝트에서 React Query 를 사용했기 때문에 좀 더 간편하게 에러를 잡을 수 있었다.

omz 코드 일부 발췌..

// article 상세 정보 받아오기
const { data, isLoading, isError, error, refetch } = useQuery("article", () =>
    getArticle(boardId, memberId)
  );

if (isError) return <p className="title">Error...</p>; 
  • React Query 에서는 isError 로 error 가 났는지 안났는지 확인할 수 있고 error 로 어떤 에러인지 확인할 수 있다.

즉, error code 또는 메시지등을 활용하여 보다 정확한 오류의 원인에 따라 사용자에게 가이드를 주거나 안내를 할 수 있다.


💗 예상 가능 & 해결 가능한 에러

인증 에러 - 401 Unauthorized Error

  • 아래와 같이 로그인을 하지 않았다면 로그인을 할 수 있도록 모달을 띄워 안내했다.

221097194-8912528f-66f2-43ad-9cb7-4cdfe129ae14

잘못된 접근으로 인한 에러 - 404 Not Found!

  • 잘못된 페이지나 없는 페이지를 접근할 경우 custom 404 page 를 보여주거나 다른 페이지로 넘어갈 수 있도록 리다이렉트하는 등의 안내를 통해 사용자에게 접근할 수 없다는 의미를 알려준다.
404@2x

어플리케이션에서 정의한 에러 - Try Catch 를 이용해서 가이드를 줘야 한다!

  • 보통 Try Catch 구문에서 Error 가 났을 경우 - 1) Alert 창을 띄워 에러가 무엇인지 알려준다. 2) 응답하는 상태코드에 따라 분기해서 에러를 처리(402, 403, 500,.. 등등) 3) 페이지를 이동 시킨다던지 4) 화면에 에러 메시지를 띄워주고 후처리 로직을 실행한다던지 등의 방법을 쓸 수 있다.

💗 예상 가능 & 해결 불가능한 에러

사용자의 고의적인 에러 / 악의적인 목적의 접근 또는 사용

  • 이 경우는 사용자가 고의적으로 비정상적인 접근을 한 경우인데 이 경우 보안상 허점이 있는 부분이니 에러 처리를 잘 해주어야 한다.

💗 예상 불가능 & 해결 가능한 에러

일시적인 네트워크 에러

  • 가장 쉬운 해결책은 '일시적인 에러' 임을 말해주고 바로 이전 액션을 다시 시도할 수 있는 가이드를 제공해주는 것이다.
  • 또한 react-adaptive-hooks 를 사용해 일시적으로 네트워크 상태가 좋지않을 때, 응답이 지연될 수 있다는 메세지를 노출시키는 것도 방법이다.

💗 예상 불가능 & 해결 불가능한 에러

브라우저에서 발생하는 에러 / 서비스 장애 상황

  • 이 에러들의 경우에는 사용자가 스스로 해결해나갈 수 없는 오류이기 때문에 예를 들면 고객센터로 진입할 수 있게 해준다던지 등으로 에러핸들링을 할 수 있다.

  • 또한 개발자의 제어권 밖에 있는 에러이기 때문에 Sentry 같은 도구를 사용해 모니터링을 수시로 해서 사용자가 해당 화면을 마주할 일이 없도록 수정해야 한다.


⭐ 결론 및 회고

길게 쓰긴 했지만 결국에는 에러를 잘 잡아서 사용자에게 에러 상황을 인지시키도록 적절한 대응을 하라는 말이다.

지금까지 진행한 프로젝트들을 생각해봤을 때, 에러 핸들링에 대해 깊게 고민한 적이 없는 것 같다. 404 page 나 로그인 안한 사람 막는 것 정도, API 호출할 때 error 찍어보는 정도? 로만 사용을 했었다. 그러다 보니 배포 후에 많은 부분에서 문제가 생겨 고쳐야 했고 결국엔 고치지 못하고 넘긴 경우도 많았다. 또한 프론트 팀원들간의 합의 없이 진행하다 보니 각자의 방식이 다 달랐다. (나같은 경우는 그냥 Error 가 뭔지만 띄워주었는데, 다른 팀원은 그냥 메인 화면으로 보내버린다던지..)

결국 프로젝트를 시작하기 전, 에러 핸들링에 대한 합의가 필요하다. Alert 창을 띄워줄 거면, 백앤드에서 에러 메세지를 어떻게 달라고 할 건지, 아니면 작은 에러의 경우 그냥 메세지만 띄워주고 넘어갈 건지 등등 사전 합의를 하고 진행을 해야 한다..

물론 다른 팀들은 에러 핸들링을 잘 하고 넘어갔을수도 있는데 나 같은 경우는 에러핸들링에 대한 고민을 해본적이 없어서 에러에 대한 고민을 해볼 수 있는 시간이었다. 물론 아직 많이 모르겠지만, 프로젝트를 진행하다보면 효율적인 에러 처리 방법을 찾을 수 있을 것이라 생각한다 ..!!


📒 참고

https://catsbi.oopy.io/92cfa202-b357-4d47-8de2-b9b3968dfb2e
https://www.youtube.com/watch?v=FXtooPhupr4
https://yjohbjects.tistory.com/6
https://jbee.io/react/error-declarative-handling-2/
https://tecoble.techcourse.co.kr/post/2021-08-13-react-error-handling/

Image by A K from Pixabay

0개의 댓글