개요
과거 오류 처리는 오류 코드를 통해서 했다.
예외는 프로그래밍 언어에서 제공하는 독립적인 오류 처리 메커니즘이다
오류가 발견되면 예외를 던지고, 생성된 예외는 적절한 예외 핸들러를 찾을 때까지 콜스택을 타고 위로 전파된다.
예외를 사용하면 오류코드를 일일이 검사하거나 오류를 식별하는 일을 신경 쓰지 않아도 된다.
예외는 정확히 예상 밖의 동작일 때만 쓰여야 한다.
판단하기 도움되는 기준은 예외를 던지는 코드를 프로그램 종료 코드로 바꿔도 프로그램이 여전히 정상동작하는지 보는것이다. 정상 동작하지 않는다면 예외를 사용하지 말고, 오류를 검출하여 프로그램을 정상 흐름으로 되돌려야 한다.
예시
전역 테이블에서 배송지의 배송 규칙을 알아내는 코드
function localShippingRules(country){//country 는 항상 유효함을 가정 const data = countryData.shippingRules[country]; if(data) return new shippingRules(data); else return -23; //오류 } function calculateShippingCosts(anOrder){ //코드들... const shippingRules = localShippingRules(anOrder.country); if(shippingRules < 0) return shippingRules; //오류 전파 //코드들... } const status = calculateShippingCosts(orderData); if(status < 0) errorList.push({order:orderData, errorCode:statuts}); |
try {//최상위 예외 핸들러를 만든다. const status = calculateShippingCosts(orderData); } catch (error) {/*예외처리*/} if(status < 0) errorList.push({order:orderData, errorCode:statuts}); |
//최상위 let status; //스코프 문제로 선언과 초기화를 어쩔 수 없이 분리 try { status = calculateShippingCosts(orderData); } catch (error) {/*예외처리*/} if(status < 0) errorList.push({order:orderData, errorCode:statuts}); |
//최상위 let status; try { status = calculateShippingCosts(orderData); } catch (error) {throw error;}//잡은 예외 다시 던지기 if(status < 0) errorList.push({order:orderData, errorCode:statuts}); |
//최상위 let status; try { status = calculateShippingCosts(orderData); } catch (error) { if(error instanceof OrderProcessingError) errorList.push({order:orderData, errorCode:statuts}); else throw error; throw error; } if(status < 0) errorList.push({order:orderData, errorCode:statuts}); //별도 추가된 예외만들 처리하는 경우 처리방식 class OrderProcessingError extends Error{ constructor(errorCode){ super(`주문 처리 오류 : ${errorCode}`); this.code = errorCode; } get name(){return "OrderProcessingError";} } |
function localShippingRules(country){//country 는 항상 유효함을 가정 const data = countryData.shippingRules[country]; if(data) return new shippingRules(data); //오류 코드 대신 예외를 던진다. else return new OrderProcessingError(-23); } |
function calculateShippingCosts(anOrder){ //코드들... const shippingRules = localShippingRules(anOrder.country); //이 상태로 두고 아직 오류 코드를 다 못처리한 부분있는지 테스트 if(shippingRules < 0) return new Error("오류 코드가 다 사라지지 않았습니다."); //코드들... } |
function localShippingRules(country){//country 는 항상 유효함을 가정 const data = countryData.shippingRules[country]; if(data) return new shippingRules(data); //오류 코드 대신 예외를 던진다. else return new OrderProcessingError(-23); } function calculateShippingCosts(anOrder){ //코드들... const shippingRules = localShippingRules(anOrder.country); //코드들... } //최상위 try { calculateShippingCosts(orderData); } catch (error) { if(error instanceof OrderProcessingError) errorList.push({order:orderData, errorCode:statuts}); else throw error; throw error; } class OrderProcessingError extends Error{ constructor(errorCode){ super(`주문 처리 오류 : ${errorCode}`); this.code = errorCode; } get name(){return "OrderProcessingError";} } |
'IT책, 강의 > 리팩터링' 카테고리의 다른 글
12 - 상속 다루기 - 메서드 올리기 (0) | 2023.10.09 |
---|---|
11 - API 리팩터링 - 예외를 사전확인으로 바꾸기 (0) | 2023.09.23 |
11 - API 리팩터링 - 수정된 값 반환하기 (0) | 2023.09.21 |
11 - API 리팩터링 - 명령을 함수로 바꾸기 (0) | 2023.09.20 |
11 - API 리팩터링 - 함수를 명령으로 바꾸기 (1) | 2023.09.19 |