프로그래밍/Javascript

자바스크립트 예외 처리 마스터하기: 사용자 정의 예외를 활용한 고급 오류 관리 기법

shimdh 2025. 2. 13. 10:07
728x90

프로그래밍에서 예외 처리는 예상치 못한 오류 발생 시 프로그램의 안정성을 유지하고 사용자에게 원활한 경험을 제공하는 데 필수적인 요소입니다. 자바스크립트에서는 try, catch, finally 블록을 사용하여 예외를 효과적으로 처리할 수 있습니다. 특히 사용자 정의 예외를 활용하면 오류를 더욱 세분화하고 맞춤형으로 처리하여 코드의 가독성을 높이고 유지보수를 용이하게 만들 수 있습니다.

1. 기본적인 예외 처리 구조: try-catch-finally 블록 이해하기

자바스크립트의 기본적인 예외 처리 구조는 try-catch-finally 블록으로 구성됩니다. 각 블록의 역할은 다음과 같습니다.

  • try 블록: 예외가 발생할 가능성이 있는 코드를 포함합니다.
  • catch 블록: try 블록에서 발생한 예외를 처리합니다. 예외 객체를 인자로 받아 오류 종류에 따라 적절한 대응을 수행합니다.
  • finally 블록: try 블록과 catch 블록의 실행 여부와 관계없이 항상 실행됩니다. 주로 파일 닫기, 네트워크 연결 종료 등 리소스 정리 작업에 활용됩니다.
try {
    // 오류 발생 가능성이 있는 코드
    let result = riskyFunction();
} catch (error) {
    // 오류 처리
    console.error("오류 발생:", error.message);
    if (error instanceof CustomError) {
        console.error("사용자 정의 오류 발생:", error.detail);
    }
} finally {
    // 항상 실행되는 코드 (리소스 정리 등)
    console.log("처리 완료");
}

2. 사용자 정의 예외: 맞춤형 오류 처리를 위한 핵심 도구

자바스크립트는 기본적으로 Error 객체를 제공하지만, 특정 상황에 맞는 상세한 오류 정보를 전달하고 맞춤형 처리를 수행하기 위해 사용자 정의 예외 클래스를 생성할 수 있습니다. 사용자 정의 예외는 Error 클래스를 상속받아 만들 수 있으며, 다음과 같은 장점을 가집니다.

  • 명확한 오류 분류: 오류 종류를 세분화하여 코드 가독성을 높이고 오류 처리를 효율적으로 관리할 수 있습니다.
  • 풍부한 오류 정보: 오류 메시지 외에 추가 정보를 담아 오류 발생 원인을 명확하게 파악할 수 있도록 돕습니다.
  • 맞춤형 오류 처리: 특정 예외에 대한 맞춤형 처리 로직을 구현하여 상황에 맞는 적절한 대응을 수행할 수 있습니다.

2.1 사용자 정의 에러 클래스 만들기

class CustomError extends Error {
    constructor(message, detail) {
        super(message);
        this.name = "CustomError";
        this.detail = detail;
    }
}

function checkValue(value) {
    if (value < 0) {
        throw new CustomError("값이 음수일 수 없습니다.", "입력 값은 0 이상이어야 합니다.");
    }
}

try {
    checkValue(-1);
} catch (error) {
    console.error(`${error.name}: ${error.message}`);
    console.error("오류 상세 정보:", error.detail);
}

2.2 실제 활용 사례: 입력 값 검증 및 API 응답 처리

사용자 정의 예외는 입력 값 검증, API 응답 처리 등 다양한 상황에서 유용하게 활용될 수 있습니다.

  • 입력 값 검증 예시:
class ValidationError extends Error {}

function validateUserInput(input) {
    if (!input.username || input.username.length < 3) {
        throw new ValidationError("사용자 이름은 최소 3글자 이상이어야 합니다.");
    }
}

try {
    validateUserInput({ username: "ab" });
} catch (error) {
    if (error instanceof ValidationError) {
        console.error(`입력 검증 실패: ${error.message}`);
    }
}
  • API 응답 처리 예시:
class APIError extends Error {
    constructor(message, statusCode) {
        super(message);
        this.statusCode = statusCode;
    }
}

function fetchUserData(userId) {
    return fetch(`/api/users/${userId}`)
        .then(response => {
            if (!response.ok) {
                throw new APIError("사용자 정보를 가져오는 데 실패했습니다.", response.status);
            }
            return response.json();
        });
}

fetchUserData(123)
    .catch(error => {
        if (error instanceof APIError) {
            console.error(`API 오류: ${error.message}, 상태 코드: ${error.statusCode}`);
        } else {
            console.error("알 수 없는 오류:", error.message);
        }
    });

3. 예외 처리 심화: try-catch-finally 블록 중첩 및 예외 되던지기

try-catch-finally 블록은 중첩해서 사용할 수 있으며, 예외를 다시 던지는 (re-throwing) 기능을 통해 더욱 복잡한 오류 처리 로직을 구현할 수 있습니다.

  • 블록 중첩 예시:
try {
    try {
        riskyFunction();
    } catch (innerError) {
        console.error("내부 try 블록에서 오류 발생:", innerError.message);
        throw innerError;
    }
} catch (outerError) {
    console.error("외부 try 블록에서 오류 발생:", outerError.message);
}
  • 예외 되던지기 예시:
function processData(data) {
    try {
        if (data.length === 0) {
            throw new Error("데이터가 비어있습니다.");
        }
    } catch (error) {
        console.error("데이터 처리 중 오류 발생:", error.message);
        throw error;
    }
}

try {
    processData([]);
} catch (error) {
    console.error("최상위 블록에서 오류 발생:", error.message);
}

결론: 효과적인 예외 처리를 통한 견고한 프로그램 개발

예외 처리는 프로그램의 안정성을 높이고 사용자 경험을 향상시키는 데 필수적인 요소입니다. 사용자 정의 예외를 적극적으로 활용하고 try-catch-finally 블록을 효과적으로 구성하여 예상치 못한 오류 상황에 유연하게 대처할 수 있는 견고한 프로그램을 개발해야 합니다.

728x90