Error handling

김상연·2022년 12월 10일

JavaScript

목록 보기
14/19

당연히 try ... catch(err)를 사용한다. catch 블럭에 인자로 들어오는 놈은 built-in error 객체인데, 아래와같은 속성을 가졌다.

  • 반드시 포함 돼 있다.
    - name : error객체의 constructor
    - message
  • 필수는 아니지만 대부분의 환경에서 지원한다.
    - stack : 콜스택(위치)

stack의 경우 name : message at call stack 형식으로 나온다.

rethrowing

try 블럭 안에서도 여러가지 에러가 발생 할 수 있다. 어떤 에러가 일어났는지에 따라 서로 다른 대응이 필요 할 수 있다.

에러 객체는 new 연산자를 통해 생성되는 만큼 instanceof 연산자로 구분 해 줄 수 있다.

let error = new Error(message);
let error = new SyntaxError(message);
let error = new ReferenceError(message);
...

이런 내장 에러 객체 또는 직접 throw로 만들어낸 에러 객체를 구분하여 대응 해 준다. 로깅을 하거나 user에게 메시지를 띄우거나 에러를 유발한 동작을 재시도 하거나...

다만 이때 예상치못한 에러가 발생할 경우를 대비해 해당 에러를 catch 블럭 안에서 다시 throw 해주는 것을 rethrowing이라 한다. 이 에러도 당연히 try ...catch로 받아줘야한다. 한층 바깥에 try ...catch를 써 주는 것이다.

wrapping exeption

에러 객체는 구체적이어야 좋다. 구체적일수록 디버깅 할 때 덜 헤매기 때문이다. 하지만 모든 에러 핸들링이 디버깅을 위해서만 존재하진 않는다. 그냥 에러의 종류에 따라 어떻게 대응해야하는지만 달라질 수 도 있다. 예를들어 요청한 데이터가 없다는 사실만 알면 충분한 상황에서 무엇때문에 없는지까지는 과한 정보일 수 있다.

아래처럼 몇가지 에러를 묶어(wrapping)하고, 속성에 구체적인 내용을 담아서 시기 적절하게 사용할 수 있다.

class ReadError extends Error {
  constructor(message, cause) {
    super(message);
    this.cause = cause;
    this.name = 'ReadError';
  }
}

class ValidationError extends Error { /*...*/ }
class PropertyRequiredError extends ValidationError { /* ... */ }

function validateUser(user) {
  if (!user.age) {
    throw new PropertyRequiredError("age");
  }

  if (!user.name) {
    throw new PropertyRequiredError("name");
  }
}

function readUser(json) {
  let user;

  try {
    user = JSON.parse(json);
  } catch (err) {
    if (err instanceof SyntaxError) {
      throw new ReadError("Syntax Error", err);
    } else {
      throw err;
    }
  }

  try {
    validateUser(user);
  } catch (err) {
    if (err instanceof ValidationError) {
      throw new ReadError("Validation Error", err);
    } else {
      throw err;
    }
  }

}

try {
  readUser('{bad json}');
} catch (e) {
  if (e instanceof ReadError) {
    console.log(e);
    // Original error: SyntaxError: Unexpected token b in JSON at position 1
    console.log("Original error: " + e.cause);
  } else {
    throw e;
  }
}
profile
리눅스와 컴퓨터 프로그래밍

0개의 댓글