제어 흐름 예외 처리 (Control Flow with Exceptions)
자바스크립트에서 예외 처리는 코드가 예상치 못한 상황에 부딪혔을 때 흐름을 조정하는 강력한 방법이다. try-catch와 throw를 활용하면 에러를 잡아내고, 그에 맞춰 로직을 유연하게 다룰 수 있다. 이번에는 예외 처리를 통해 제어 흐름을 어떻게 관리할 수 있는지, 알아보려고 한다.
예외를 잘 다루면 코드가 더 안정적이고 읽기 쉽게 변한다. 단계별로 하나씩 살펴보자.
try-catch의 기본 구조
try-catch
는 에러가 발생할 가능성이 있는 코드를 감싸고, 에러가 나면 그걸 잡아서 처리한다. 간단한 예시로 시작해보자:
try {
let result = undefinedVariable;
console.log(result);
} catch (error) {
console.log("문제가 생겼다: " + error.message);
} // "문제가 생겼다: undefinedVariable is not defined"
try
안에서 정의되지 않은 변수를 호출하면 에러가 발생하고, catch
가 그걸 잡아서 메시지를 출력한다. 이 기본 구조를 이해하면 흐름을 제어하는 첫걸음이 된다.
1. throw로 사용자 정의 에러 던지기
throw
를 쓰면 특정 조건에서 의도적으로 에러를 발생시킬 수 있다. 이를 통해 흐름을 원하는 방향으로 바꿀 수 있다:
function divide(a, b) {
if (b === 0) {
throw new Error("0으로 나눌 수 없다!");
}
return a / b;
}
try {
let result = divide(10, 0);
console.log(result);
} catch (error) {
console.log("에러: " + error.message);
} // "에러: 0으로 나눌 수 없다!"
0으로 나누려는 시도를 throw
로 막고, catch
에서 처리했다. 이렇게 하면 코드가 비정상적으로 끝나는 걸 막을 수 있다.
2. finally로 항상 실행되는 코드 추가
finally
는 에러가 나든 안 나든 무조건 실행되는 블록이다. 정리 작업을 할 때 유용하다:
try {
console.log("작업 시작");
throw new Error("강제로 에러 발생");
} catch (error) {
console.log("잡았다: " + error.message);
} finally {
console.log("작업 끝, 정리 완료");
}
// "작업 시작"
// "잡았다: 강제로 에러 발생"
// "작업 끝, 정리 완료"
finally
는 에러 여부와 상관없이 마지막에 실행된다. 자원을 정리하거나 마무리 로직을 넣기에 딱 맞다.
3. 중첩된 try-catch로 세밀한 제어
try-catch
를 중첩하면 에러를 더 세밀하게 다룰 수 있다:
try {
try {
throw new Error("내부 에러");
} catch (innerError) {
console.log("내부에서 잡음: " + innerError.message);
throw new Error("외부로 전달");
}
} catch (outerError) {
console.log("외부에서 잡음: " + outerError.message);
}
// "내부에서 잡음: 내부 에러"
// "외부에서 잡음: 외부로 전달"
안쪽에서 에러를 잡고, 필요하면 다시 던져서 바깥에서 처리했다. 이런 식으로 계층적으로 흐름을 조정할 수 있다.
4. 조건에 따른 흐름 분기
예외 처리를 조건문과 섞으면 흐름을 더 유연하게 만들 수 있다:
function checkValue(value) {
try {
if (value < 0) {
throw new Error("음수는 안 된다");
}
console.log("값이 유효하다: " + value);
} catch (error) {
console.log("문제 발생: " + error.message);
}
}
checkValue(5); // "값이 유효하다: 5"
checkValue(-3); // "문제 발생: 음수는 안 된다"
조건에 따라 에러를 던지고, 그에 맞춰 흐름을 분기했다. 입력값을 검증할 때 특히 유용하다.
5. 비동기 코드에서의 예외 처리
비동기 작업에서는 try-catch
를 약간 다르게 써야 한다. Promise와 함께 보자:
function fetchData() {
return new Promise((resolve, reject) => {
reject(new Error("데이터 가져오기 실패"));
});
}
async function process() {
try {
await fetchData();
} catch (error) {
console.log("비동기 에러: " + error.message);
}
}
process(); // "비동기 에러: 데이터 가져오기 실패"
async/await
와 함께 쓰면 비동기 에러도 깔끔하게 잡아낸다. 비동기 흐름을 제어할 때 필수적인 방법이다.
6. 커스텀 에러 객체 활용
기본 Error
대신 커스텀 에러를 만들어 쓰면 더 구체적으로 흐름을 다룰 수 있다:
class ValidationError extends Error {
constructor(message) {
super(message);
this.name = "ValidationError";
}
}
function validate(input) {
if (!input) {
throw new ValidationError("입력값이 비었다");
}
console.log("입력값: " + input);
}
try {
validate("");
} catch (error) {
console.log(error.name + ": " + error.message);
} // "ValidationError: 입력값이 비었다"
커스텀 에러를 만들면 에러의 종류를 구분해서 처리하기 쉬워진다.
7. 에러를 활용한 복잡한 흐름 제어
예외를 적극적으로 활용하면 복잡한 로직도 깔끔하게 정리된다:
function processUser(user) {
try {
if (!user.name) {
throw new Error("이름이 없다");
}
if (user.age < 18) {
throw new Error("미성년자다");
}
console.log(`처리 완료: ${user.name}, ${user.age}세`);
} catch (error) {
console.log("처리 실패: " + error.message);
}
}
processUser({ name: "철수", age: 20 }); // "처리 완료: 철수, 20세"
processUser({ name: "영희", age: 15 }); // "처리 실패: 미성년자다"
여러 조건을 검사하고, 문제가 생기면 바로 에러를 던져서 흐름을 중단했다. 복잡한 조건문 대신 예외로 처리하니 깔끔해졌다.
8. 성능과 가독성에 미치는 영향
예외 처리가 성능과 가독성에 어떤 영향을 주는지 보자:
- 성능: 예외 처리는 약간의 오버헤드가 있지만, 코드가 비정상적으로 끝나는 걸 막아 안정성을 높인다.
- 가독성: 긴 조건문 대신 에러를 던지고 잡으면 로직이 명확해진다.
throw로 의도적인 흐름 변경과 finally로 정리 작업을 보장하는 점이 예외 처리의 강점이다.
마무리
예외 처리는 단순히 에러를 잡는 데 그치지 않는다. try-catch
, throw
, finally
를 통해 흐름을 세밀하게 조정하고, 비동기와 커스텀 에러까지 다루면 코드가 더 튼튼해진다. 이런 도구들을 잘 활용하면 안정적이고 깔끔한 코드를 만들 수 있다.
'코딩 공부 > 자바스크립트' 카테고리의 다른 글
58. 자바스크립트 에러 핸들링 전략 (Error Handling Strategies) (1) | 2025.03.19 |
---|---|
57. 자바스크립트 커스텀 에러 클래스 (Custom Error Classes) (1) | 2025.03.19 |
55. 자바스크립트 break와 continue 심화 (Break and Continue Deep Dive) (1) | 2025.03.18 |
54. 자바스크립트 스위치 문 활용 (Advanced Switch Statement Usage) (3) | 2025.03.18 |
53. 자바스크립트 루프 최적화 (Loop Optimization) (1) | 2025.03.17 |