우테코 프리코스 과제를 하다가 기능요구사항에 이런 조건이 있었다.
사용자가 잘못된 값을 입력한 경우 throw문을 사용해 예외를 발생시킨후 애플리케이션은 종료되어야 한다.
if 문과 return으로 함수를 끝내면 되지 않나 ? throw는 뭐가 다른걸까? 라는 생각이들었다.
먼저 공식문서를 찾아보았다.
1. Throw 개념
throw문은 사용자 정의 예외를 발생(throw)할 수 있습니다. 예외가 발생하면 현재 함수의 실행이 중지되고 throw 이후의 명령문은 실행되지 않습니다. 제어 흐름은 콜스택의 첫 번째 catch 블록으로 전달됩니다.
호출자 함수 사이에 catch 블록이 없으면 프로그램이 종료됩니다.
function getRectArea(width, height) {
if (isNaN(width) || isNaN(height)) {
throw 'Parameter is not a number!';
}
}
try {
getRectArea(3, 'A');
} catch (e) {
console.error(e);
// expected output: "Parameter is not a number!"
}
예제
예외 값으로 객체 사용하기
예외를 발생시킬 때 객체를 명시할 수 있습니다. 그러면 catch 블록에서 객체의 속성을 참조 할 수 있습니다.
다음 예제에서는 UserException 타입의 객체를 만들고 throw 구문에서 이 객체를 사용합니다.
function UserException(message) {
this.message = message;
this.name = 'UserException';
}
function getMonthName(mo) {
mo = mo - 1; // 월 숫자를 배열의 인덱스 값과 맞추기 위해서 입니다.(1 = 1월, 12 = 12월)
var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul',
'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
if (months[mo] !== undefined) {
return months[mo];
} else {
throw new UserException('InvalidMonthNo');
}
}
try {
// try 문
var myMonth = 15; // 15 는 범위를 벗어났기 때문에 예외를 발생시킵니다
var monthName = getMonthName(myMonth);
} catch (e) {
monthName = 'unknown';
console.error(e.message, e.name); // 오류 처리기에 예외 객체를 전달합니다
}
2. 언제 사용될까 ?
const errorFun = () => {
throw new Error('some error')
}
function testFun() {
errorFun()
console.log('hello')
}
testFun()
이 예제는 throw로 에러처리를 한 경우이다.
스레드가 멈추고 console.log가 실행되지 않는다.
다음은 try catch를 추가하여 에러가 나와도 스레드를 계속 실행하도록 하고 에러를 핸들링 할 수 있게 했다.
const errorFun = () => {
throw new Error('some error')
}
function testFun() {
try {
errorFun()
} catch (error) {
console.log(error)
}
console.log('hello')
}
testFun()
다음과 같이 함수가 여러 depth로 있는 경우에도 똑같이 작동한다.
const errorFunB = () => {
console.log("errorFunB")
throw new Error('some error')
}
const errorFunA = () => {
console.log("errorFunA")
errorFunB)
}
function testFun() {
try {
errorFunA()
} catch (error) {
console.log(error)
}
console.log('hello')
}
testFun()
이제 내가 알던 return으로 에러처리를 해보자
const FuncB = () => {
console.log("FuncB excutin")
return {
error: new Error("some error")
}
}
const FuncA = () => {
console.log("FuncA executin")
const result = FuncB
if(result.error){
return {
error: new Error(`rror occured : details ${result.error}`)
}
}
}
function test() {
if(result.error){
console.log(result.error)
}
console.log('hellow')
}
test()
이 경우 에러메세지가 더 자세히 표현된다. 또한 try catch를 하지 않아도 스레드가 중지되지 않는다.
하지만 단점이 존재한다. FuncB함수 안에 또 다른 함수를 불러 에러처리를 해야한다면 각 레벨에서 에러 처리를 해야하기에 불편한 작업이 될 것이다.
따라서 2가지 에러처러중 선택해서 사용하면 되지만 메세지를 세분화하여 컨트롤하고 싶으면 return을 사용하면 되고 여러 depth의 에러를 한 번에 잡아 처리하고 싶으면 throw를 사용하면 된다.
source : MDN throw
'정보 > The 공부' 카테고리의 다른 글
클린코드 연습하기 ( 함수 분리 / 클래스[객체]분리) (0) | 2022.11.11 |
---|---|
[JS - 심화] TDD란? (0) | 2022.11.06 |
[고찰] 상처 받지 않으면서 피드백 주고 받기 (1) | 2022.11.04 |
[클린코드] 어떻게 의미 있는 이름을 지을 수 있을까? (0) | 2022.10.31 |
[JS - 심화] 왜 else , else if문을 지양해야 할까 ? (0) | 2022.10.28 |