JavaScript

[JavaScript] throw와 return의 차이

반응형

문득 다른사람의 코드를 보다가 에러처리하는 방법에 의구심이 생겼습니다. throw와 return 둘의 역할이 비슷한거 같은데 정확히 어떤 차이 때문에 구분해서 쓸까 궁금했습니다. 자료를 찾다보니 medium의 글이 있어서 참고하였습니다.

 

const inner1 = () => {
  throw new Error('some error')
}

function main() {
  inner1()
  console.log('I am waiting')
}

main()

위는 throw로 에러처리를 한 경우입니다. 스레드가 멈추고 console이 실행되지 않습니다.

 

다음은 try catch를 추가하여 에러가 나와도 스레드를 계속 실행하도록하고 에러를 핸들링할 수 있게 했습니다.

 

const inner1 = () => {
  throw new Error('some error')
}
function main() {
  try {
    inner1()
  } catch (error) {
    console.log(error)
  }
  console.log('I am waiting')
}

main()

다음과 같이 함수가 여러 depth로 있는 경우에도 똑같이 작동합니다.

 

const inner2 = () => {
  console.log('inner2 executing')
  throw new Error('some error')
}
const inner1 = () => {
  console.log('inner1 executing')
  inner2()
}

function main() {
  try {
    inner1()
  } catch (error) {
    console.log(error)
  }
  console.log('I am waiting')
}

main()

 

이제 return으로 에러처리하는 방법을 살펴봅시다.

 

const inner2 = () => {
  console.log('inner2 executing')
  return {
    error: new Error('some error')
  }
}

const inner1 = () => {
  console.log('inner1 executing')
  const result = inner2()
  if (result.error) {
    return {
      error: new Error(`error occured : details ${result.error}`)
    }
  }
}

function main() {
  if (result.error) {
    console.log(result.error)
  }

  console.log('I am waiting')
}

main()

이 경우 에러메세지가 더 자세히 표현됩니다. 또한 try catch를 하지 않아도 스레드가 중지되지 않는다는 것을 알 수 있습니다.

하지만 단점이 있습니다. inner함수 안에 또 다른 함수를 불러 에러처리를 해야한다면 각 레벨에서 에러처리를 해야하기에 불편한 작업이 될 것입니다.

 

따라서 2가지 에러처리중 선택해서 사용하면 되지만 메세지를 세분화하여 컨트롤하고 싶으시면 return을 사용하면 되고 여러 depth의 에러를 한 번에 잡아 처리하고 싶으시다면 throw를 사용하시면 됩니다.

 

const inner3 = () => {
  console.log('inner3 executing')
  throw new Error('some error')
}

const inner2 = () => {
  console.log('inner2 executing')
  inner3()
}

const inner1 = () => {
  console.log('inner1 executing')
  try {
    inner2()
  } catch (error) {
    return {
      error: new Error(`error occured : details ${error}`)
    }
  }
}

function main() {
  const result = inner1()
  if (result.error) {
    console.log(result.error)
  }

  console.log('I am waiting')
}

main()

 

위 예시를 보면 inner2()보다 깊은 에러는 신경쓰지 않습니다. 모든 에러를 inner1()에서 잡아서 main으로 보내줘서 어떤 에러가 들어오든 볼 수 있습니다.

 

요약하자면 두가지 방식의 에러처리로 유연한 코딩이 가능해집니다.

 

추가로 throw 이후에 코드는 실행되지 않기 때문에 return을 추가할 필요는 없습니다.

 

 

 

 

[참고]

https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Statements/throw

 

throw - JavaScript | MDN

throw문은 사용자 정의 예외를 발생(throw)할 수 있습니다. 예외가 발생하면 현재 함수의 실행이 중지되고 (throw 이후의 명령문은 실행되지 않습니다.), 제어 흐름은 콜스택의 첫 번째 catch 블록으로

developer.mozilla.org

https://medium.com/@junchenp1018/differences-in-javascript-with-throwing-and-return-error-d8c0e901c083

 

Differences in Javascript with throwing and return error

This blog is to differentiate the throwing an error with returning an error. In project, I found different people have different ways of…

medium.com

 

반응형