Error Handling

Gaeun·2023년 1월 3일
0

wecode TIL

목록 보기
14/24

1. 에러 핸들링 목적과 의의

1-1. 에러 핸들링 목적

에러 핸들링: 사용자가 서비스를 이용하는 동안 발생할 수 있는 에러를 미리 사전에 예측하여, 이용자의 사용 흐름이 막히지 않도록 유도하는 것.

1-2. 에러 핸들링 의의

에러 핸들링은 엄밀히 말해 에러 핸들링(Error Handling)예외 핸들링(Exception Handling) 두 가지 종류로 구분된다. 에러는 컴퓨터가 내지만, 예외는 개발자가 의도적으로 발생시키는 것이다.

1-2-1. 에러

에러: 언어의 문법 에러, 통신 장애로 발생하는 에러 등 컴퓨터가 코드를 실행하는 과정 자체에서 발생하는 에러

const numberOne = 1
consloe.log(numberOne) // 함수 이름 오류 `console.log`

//  Uncaught ReferenceError: consoel is not defined 

위와 같은 경우는 개발자가 의도적으로 만들어낸 에러가 아닌, (실수로 오타를 내어서) 컴퓨터가 자바스크립트 문법을 실행하는 과정 자체에서 더이상 진행할 수 없어서 발생한 에러이다.

1-2-2. 예외

예외: 언어가 실행되는 과정 자체에는 큰 문제가 없지만, 개발자와 개발팀이 판단하기에 정상적인 상황이 아닌 과정

회원가입 상황에서는 아래와 같은 규칙을 정했다고 가정해보자.

  1. 회원가입에 사용되는 이메일에는 @가 들어가야 한다.
  2. 비밀번호를 10자 이상 지정하도록 한다.
  3. 회원가입에 사용되는 계정은 중복될 수 없다.

이런 상황에서 유저가 비밀번호를 5자리만 설정한다면, 개발자의 의도와는 다른 방향으로 유저가 서비스를 이용하고자 하므로 예외 사항에 해당한다. 따라서, 개발자는 예상되는 예외 상황들을 나열하여, 잘못된 방법으로 서비스를 이용하는 것을 막아야 한다.

따라서 아래와 같은 예외 처리가 필요하다.

  1. 회원가입에 사용되는 이메일에 @ 가 들어가지 않으면 에러 반환
  2. 비밀번호가 10자 미만이라면 에러 반환
  3. 이미 가입되어 있는 계정으로 가입 시도를 할 때 에러 반환

이와 같은 예외 상황은 엄밀히 말해 컴퓨터 언어 입장에서는 에러가 아니다. 문법이 틀리지 않았고, 함수를 정상적으로 호출했을 수 있기 때문이다.

하지만 이런 예외 상황은 함수 내부에서 미리 if문 등으로 처리를 해두어야 한다. 잘못된 방식으로 서비스를 이용하기 전에 예외 상황을 미리 일으켜 에러를 발생시키고, 클라이언트(프론트엔드) 개발자에게 에러 상황 에러 코드로 알린다. 프론트엔드 개발자는 아래 에러를 반환받아서, 사용자(고객)에게 적절한 안내 문구를 띄워준다.

const { email, password } = req.body

if (!email.includes('@')) {
  return new Error('EMAIL_INVALID')
}

if (password.length < 10) {
  return new Error('PASSWORD_INVALID')
}
...

예외 발생 전 사전 처리, 발생한 에러를 잡아내고 처리하는 모든 과정을 에러 핸들링이라 일컫는다.

2. throw와 try-catch

2-1. throw

위 예시에서는 특정 예외 상황에서 에러를 return했는데, 이 방법은 에러를 발생시키는 일반적인 방법은 아니다. 여러 프로그래밍 언어에서(자바스크립트를 포함하여) 에러를 발생시키는 방법은 throw이다. 아래와 같이 사용되는데, 어떤 예외 상황이며 어떤 에러인지 설명하기 위해 메시지부분이 필수로 들어간다.

throw new Error('EMAIL_INVALID')

throw new Error('message 부분')

예외 상황이 발생하면 진행하던 작업을 중단시키고 위 에러를 호출한 상위 모듈로 제어를 넘기게 된다. 즉, throw는 여기 이 지점에서 특정 에러가 발생했음을 알리고, 이 에러가 발생하면, 상위 모듈은 그에 맞는 액션(코드)를 취하게 된다.

상위 모듈은 하위에서 발생하여 넘어오는 에러에 대해 대비할 수 있다. 'A라는 에러가 발생했을 때는 B라는 처리를 해주고, C라는 에러가 발생했을 때는 D라는 방법으로 처리한다.' 등의 형태이다.

해당하는 역할은 try-catch에서 수행하도록 설계되어 있다.

2-2. try-catch

try-catch 문은 잠재적인 에러가 발생할 가능성이 있는 부분에서 에러를 처리하기 위한 용도로 사용한다. try 블록에는 에러가 발생할 가능성이 있는 코드를 넣어두고, catch 블록에는 에러가 발생했을 때를 대비한 행동을 넣어둡니다.

try 블록에서 어떠한 예외 처리를 위해 에러를 throw하면 발생한 에러가 catch 블록으로 넘어가게 됩니다. 따라서 try 블록 내부에 throw 코드가 있거나, throw 코드를 내장하고 있는 다른 함수를 호출하는 부분이 있다.

catch 블록 내부에서 또다시 에러를 throw할 수 있는데, 이러한 상황에서는 더 상위 모듈로 에러를 던지게 된다.

try {
  const { email, password } = req.body

  if (!email.includes('@')) {
    const error = new Error('EMAIL_INVALID')
    error.statusCode = 400
    throw error
  }

  if (password.length < 10) {
    const error = new Error('PASSWORD_INVALID')
    error.statusCode = 400
    throw error
  }
...
} catch (err) {
  console.log(err) // 어떠한 형태의 에러가 발생하든, 에러를 콘솔에 찍어서 개발자에게 보여준다.
  return res.json({
}

3. 에러 핸들링에서의 미들웨어

3-1. 미들웨어란?

에러 핸들링은 반복적인 작업이다. 서로 다른 기능이어도 같은 에러를 잡아야할 수 있다.

위에 언급된 아래의 두 가지 규칙은,

  1. 회원가입에 사용되는 이메일에는 @가 들어가야 한다.
  2. 비밀번호를 10자 이상 지정하도록 한다.

회원가입 기능에 포함되는 동시에, 로그인 기능에도 포함되는 규칙이다. 같은 규칙을 다른 두 기능에 중복으로 기입해야 하고, 그렇다면 코드도 중복으로 계속 기입해야 한다. 이러한 공통된 작업을 모듈화하는 용도로 개념 가운데 하나가 미들웨어이다.

Express의 미들웨어 는 컨트롤러와 컨트롤러를 이어주는 또 다른 컨트롤러의 한 종류이다. 즉, 컨트롤러 사이에 위치하여, 컨트롤러 진입 전, 공통적으로 해야하는 작업들을 처리하는 기능을 합니다. 중복되는 기능들이라고해서 전부 미들웨어로 생성하는 것은 아니다.

대표적으로 사용하는 미들웨어는 주로 CORS 정책을 설정하는 미들웨어나 서버에서 일어나는 상황을 기록(로그, log)하는 logging 미들웨어이다.

에러 핸들링 또한 미들웨어로 사용하는 것을 하며, 이는 미들웨어를 사용하면 여러 경우에 발생하는 에러 핸들링을 하나로 모을 수 있다는 장점이 있기 때문이다.

3-2. 에러 핸들링에서 미들웨어의 중요성

각 계층에서 각자의 에러를 처리하게되면, 에러 처리를 하는 계층이 너무 많아지게 된다. 이는 유지보수를 어렵게 하기 때문에 에러는 한 군데로 모아서 처리하는 것이 좋다.

예외 상황이 발생했을 때, Error를 바로 response로 반환하지 않고 throw 한다. “에러를 던진다(throw)” 라고 표현하며, 던진 에러는 에러 처리 미들웨어 한군데에서 “잡아서(catch)” 처리한다.

에러들을 한 곳으로 모으는 역할을 미들웨어가 수행하면서 동시에 로그 기능 등을 붙인다면, 에러 핸들링을 하면서 어떤 에러가 발생했었는지 기록도 할 수 있어서 에러 핸들링을 보다 다채롭게 할 수 있다. 에러 처리하는 기능을 미들웨어로 모듈화하는 것 또한 특정 기능을 분리하는 것이므로 관심사의 분리 (Seperation Of Concern | SOC)에 해당한다고 할 수 있다.

4. Summary

  • 소프트웨어는 에러와 예외가 늘 발생하여 정상적인 사용 흐름이 막히게 된다.
  • 에러 핸들링예외 핸들링 두가지 종류로 구별된다.
    • 에러 핸들링은 언어의 문법 에러, 통신 장애로 발생하는 에러등 컴퓨터가 코드를 실행하는 과정 자체에서 발생하는 에러를 처리하는 과정
    • 예외 핸들링은 정상적인 서비스 진행을 방해하는 과정으로 코드가 진행될 경우를 막기 위해 개발자가 의도적으로 발생시키는 예외 상황을 처리하는 과정
  • 일반적으로 Javascript 에서는 try-catch문과 throw를 이용하여 에러를 처리한다.
  • 에러 핸들링 미들웨어는 에러를 처리하기 위해 반복적으로 진행되는 코드를 모듈화하여 소프트웨어의 확장성과 생산성을 높이기 위해 사용한다.
profile
🌱 새싹 개발자의 고군분투 코딩 일기

0개의 댓글