에러 해결 - 11. 에러 핸들링.

이유승·2023년 7월 13일
0

에러 해결

목록 보기
11/25

기능을 구현하다보면 내부에서 단계별로 동작해야하는 코드들이 존재하기 마련이다. 그런데 기능이 수행되는 동안에 에러가 발생하였다면? 그 즉시 전체 기능을 중단하여야 한다. 이를 위해서 사용하는 개념이 바로 try-catch문이다.



1. try-catch.

try {
    console.log('ok!');
} 
catch () {
    console.log('error!');
}

try 문 내부에서는 기능 수행을 위해 동작해야하는 코드를, catch 문 내부에는 기능 수행 중 에러가 발생하였을 때 동작하는 코드를 작성하면 된다. try 문 내부에 작성한 코드를 실행하는 도중에 에러가 발생했을 경우, JS는 그 즉시 나머지 코드의 실행을 중단하고 제어권을 catch 문으로 넘긴다.

  • 의도적으로 에러를 발생시키는 방법.
    -> JS 자체적인 에러가 아닌, 특정 조건이 발동했을 때 동작을 중단하고 catch 문으로 넘어가야할 경우에는? throw new Error();로 에러를 강제로 발생시킬 수 있다.

그런데 try-catch문에서 비동기 통신이 사용되는 기능을 적용했을 경우, 에러가 발생되어도 catch 문으로 넘어가지 않는다. 그 이유는, 자바스크립트의 특성상 통신의 결과가 도달하기 전에 try 문이 모든 동작을 완료해버리기 때문이다.

예시) 출처.

try {
    setTimeout(function() {
        throw Error('에러 발생');
    }, 3000);
} 
catch (err) {
    console.log('에러 핸들링: '+ err.message);
}

console.log('코드 종료.');



2. 그렇다면 해결 방법은?

setTimeout(function() {
    try {
        throw Error('에러 발생');
    } 
    catch (err) {
        console.log('에러 핸들링: '+err.message);
    }
}, 3000);

console.log('코드 종료.');

다음과 같이 비동기 통신 작업을 수행하는 코드 내부로 try-catch문을 집어넣거나..

then-catch문을 사용하면 된다.

비동기통신()
.then(() => {
    console.log('ok!');
})
.catch((error) => {
    console.log('error!');
})

then-catch문은 사용자가 따로 코드를 추가할 필요가 없고, 에러가 발생했을 때 알아서 catch문으로 넘어가준다.

편리해졌지만, 비동기 통신을 수행하는 코드가 많아질 수록 then-catch문이 중첩되기 때문에 결과적으로 코드의 가독성이 떨어지는 문제를 가지고 있다.



3. async-await!

const connect = async () => {

  try {
    await 비동기통신();
    console.log('ok!');
  } 
  catch () {
    console.log('error!');
  };

};

기존 Promise 객체의 단점을 해결하기 위해 등장한 async, await 키워드는 위와 같은 단점을 개선할 수 있다.

  try {
    await 비동기통신1();
    await 비동기통신2();
    await 비동기통신3();
    console.log('ok!');
  } 
  catch () {
    console.log('error!');
  };

각각의 비동기통신을 수행하는 과정에서 에러가 발생할 경우 어느 지점에서든 동작을 중단하고 바로 catch 문으로 넘어가게 된다. 비동기 통신 하나마다 then-catch문을 작성했던 때와 비교해보면 코드가 굉장히 보기 좋아졌다고 할 수 있다.

다만 async, await 키워드에도 단점이 존재한다.

  try {
    const a = await 비동기통신1();
    const b = await 비동기통신2();
    const c = await 비동기통신3();
    console.log('ok!');
  } 
  catch () {
    console.log('error!');
  };

모든 코드가 try 문 내부에 존재하다보니 각각의 통신 결과값들이 한 곳에 모여 서로 접근이 가능하다. 같은 상황에서 then-catch문은 하나의 then 문은 하나의 비동기통신 결과값만을 다룰 수 있어 접근이 불가능하므로 내가 구현할 기능의 특징에 맞춰 더 나은 수단을 선택하면 된다.

  • 이 단점은 아마 보안 등의 이유로 단점이라고 하는 듯 한데, 더 자세히 알아볼 것!

  • then 문이 통신 결과값을 다루는 방법?

.then((response) => {
    console.log(response);
    // 결과값은 response으로 담아져나온다.
})
profile
프론트엔드 개발자를 준비하고 있습니다.

0개의 댓글