ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Group Study, 모던 자바스크립트 Deep Dive] - 47 에러처리
    Front-end/Javascript 2023. 4. 9. 17:05
    반응형

    47.4 throw문

    Group study background

    나만 그런건지는 모르겠지만, 실무를 하다보면 잊어버리는 개념들이 있다.

    가끔 FE 뉴비인분들에게 질문을 받는데, 아리송 할때만큼 쪽팔릴때가 없었다.

    인간은 망각의 동물이라고 교수님께서 말씀하셨지만 반복 학습의 힘을 믿는다. React 오픈카톡방에서 모집한 스터디원분들과 함께 "모던 자바스크립트 Deep Dive" 1권 톺아보기를 시작한다!

     

    정보 전달용이 아닌 개인 스터디 레코딩용 포스트입니다.


    47.1 에러 처리의 필요성

    개발자라면 비지니스 로직을 잘 짜는 것도 중요하지만 에러를 잘 핸들링 하는 것도 능력이라고 생각한다. 에러가 발생하지 않는 코드는 없기 때문인데, 에러를 "잘" 파악하기 위한 처리가 필요하다. 발생한 에러에 대해 대처하지 않으면 프로그램이 종료될 수 있다. 사실 이것보다 무서운건 "그냥" 지나가는 것인데, 파급 효과를 알 수 없기 때문에 그 중요성이 더 크다.

     


    47.2 try... catch... finally문

    기본적으로 에러 처리를 구현하는 방법은 크게 두 가지가 있다. 

    1. querySelector나 Array#find 메서드처럼 예외적인 상황이 발생하면 반환하는 값(Null || -1)을 if 문이나 단축 평가 또는 옵셔널 체이닝 연산자를 통해 확인해서 처리하는 방법
    2. 에러 처리 코드를 미리 등록해 두고 에러가 발생하면 에러 처리 코드로 점프하도록 하는 방법 (try...catch..finally가 해당)

    47.3 Error 객체

    Error 생성자 함수는 에러를 상세히 설명하는 에러 메세지를 인수로 전달하는 에러 객체를 생성한다. 

    Error 생성자 함수가 생성한 에러 객체는 message 프로퍼티와 stack 프로퍼티를 갖는다. message 프로퍼티의 값은 Error 생성자 함수에 인수로 전달한 에러메세지이고, stack 프로퍼티 값은 에러를 발생시킨 콜스택의 호출 정보를 나타내는 문자열이다(디버깅 목적). 

    생성자 함수 인스턴스
    Error 일반적 에러 객체
    SyntaxError 자바스크립트 문법에 맞지 않는 문을 해석할 떄
    ReferenceError 참조할 수 없는 식별자를 참조했을때
    TypeError 피연산자 또는 인수의 데이터 타입이 유요하지 않을 때
    RangeError 숫자값의 허용 범위를 벗어났을 때
    URIError encodeURI 또는 decodeURI 함수에 부적절한 인수를 전달했을 때 
    EvalError eval 함수에서 발생

    47.4 throw문

    에러를 발생시키려면 try 코드 블록에서 throw 문으로 에러 객체를 던져야 한다.

    throw 문의 표현식은 어떤 값이라도 상관없지만 일반적으로 에러 객체를 지정한다. 에러를 던지면 catch 문의 에러 변수가 생성되고 던져진 에러 객체가 할당되어 catch 코드 블록이 실행되기 시작한다.

    [예제 47-01]

    try {
     throw new Error('something wrong')
    } catch(error) {
     console.log(error)
    }

    47.5 에러의 전파

    45장 "프로미스"의 45.1.2절 "에러 처리의 한계"에서 살펴본 것처럼 에러는 호출자(caller) 방향으로 전파된다. 즉, 콜 스택의 아래 방향(실행 중인 실행 컨택스트가 푸시되기 직전에 푸시된 실행 컨택스트 방향)으로 전파된다.

    [예제 47-02]

    const foo = () => {
     throw Error('foo')  //4
    }
    
    const bar = () => {
     foo(); //3
    }
    
    const baz = () => {
     bar(); //2
    }
    
    try {
     baz(); //1
    } catch(err) {
     console.error(err)
    }

    1에서 baz 함수를 호출하면 2에서 bar 함수 3에서 foo 그리고 4에서 에러를 throw한다. 이때 foo 함수가 throw한 에러는 다음과 같이 호출자에게 전파되어 전역에서 캐치된다.

    throw된 에러를 캐치하지 않으면 호출자 방향으로 전파된다. 따라서 throw된 에러를 캐치하여 적절히 대응해야 프로그램에 타격을 줄이면서 코드의 실행 흐름을 복구할 수 있다. 

    setTimeout이나 프로미스 후속 처리 메서드의 콜백 함수는 호출자가 없기 때문에 주의가 필요하다. 이 두 가지 함수들은 태스크 큐나 마이크로태스크 큐에 일시 저장되었다가 콜 스택이 비면 이벤트 루프에 의해 콜 스택으로 푸시되어 실행된다. 이때 콜 스택에 푸시된 콜백 함수의 실행 컨택스트는 콜 스택의 가장 하부에 존재하게 되기 때문에 에러를 전파할 호출자가 존재하지 않는다.

    반응형

    댓글

Designed by Tistory.