자바스크립트의 try...catch는 일반적으로 코드 블록 내의 오류를 안전하게 잡아내는 구조로 많이 사용됩니다. 저 역시 동기적인(synchronous) 코드에서는 자신 있게 사용해왔습니다. 그런데 아래 두 가지 코드가 제시되었을 때, 예상치 못한 문제가 발생했습니다.
처음에는 "try...catch면 오류를 잡아낼 텐데?"라는 생각에 당황했지만, 실제로는 예상과 달리 오류가 잡히지 않았습니다. 이때 저는 익숙함이 오히려 안일함을 낳는다는 교훈을 뼈저리게 느꼈습니다.
반응형
핵심 깨달음: 비동기와 동기 오류 처리의 차이
저는 try...catch의 동작 원리를 다시 분석해보았습니다. 그 결과 중요한 사실을 깨달았습니다.
동기적 처리: try...catch는 동기적 코드 블록에서 발생한 오류를 처리할 수 있습니다.
비동기 처리의 한계:
setTimeout과 같이 비동기 함수는 콜백이 이벤트 큐에 예약되므로, try...catch 블록 실행 시점과 오류 발생 시점이 다릅니다.
Promise 역시 비동기적으로 동작하기 때문에, .then() 내에서 발생한 오류는 try...catch 범위 밖에서 발생합니다.
이러한 한계로 인해 비동기 코드에서 발생한 오류는 일반적인 try...catch로 처리할 수 없음을 알게 되었습니다.
해결책: 비동기 오류 처리를 위한 올바른 방법
비동기 환경에서 오류를 효과적으로 처리하기 위해서는 Promise나 async/await 등의 패턴을 활용해야 합니다. 아래는 개선된 코드 예시입니다.
수정된 코드 1: setTimeout과 Promise 사용
new Promise((resolve, reject) => {
setTimeout(() => {
try {
throw new Error('err');
} catch (err) {
reject(err); // 오류를 Promise로 전달
}
}, 200);
})
.then(() => {
// 성공 시 실행
})
.catch((err) => {
console.log(err); // 여기서 오류를 잡음
});
포인트: setTimeout 콜백 내부에서 try...catch를 사용하여 발생한 오류를 reject로 전달한 후, .catch()에서 처리합니다.
수정된 코드 2: Promise와 async/await 사용
방법 1: Promise 체이닝
Promise.resolve()
.then(() => {
throw new Error('err');
})
.catch((err) => {
console.log(err); // 여기서 오류를 잡음
});
방법 2: async/await 활용
async function handleError() {
try {
await Promise.resolve().then(() => {
throw new Error('err');
});
} catch (err) {
console.log(err); // 여기서 오류를 잡음
}
}
handleError();
포인트: async/await를 사용하면 비동기 코드도 마치 동기 코드처럼 처리할 수 있어, try...catch를 자연스럽게 활용할 수 있습니다.
자바스크립트의 비동기 오류 처리에 대한 이해 부족이 단순한 실수로 이어졌지만, 이를 통해 지속적인 학습과 겸손함의 중요성을 다시 한 번 깨닫게 되었습니다.