본문 바로가기
C.W.K.
Stream
Lesson 05 of 05 · published

비동기 오류 다루기: `unknown`에서 책임 있는 복구까지

~8 min · async-promises, errors, unknown, try-catch

Level 0Curious
0 XP0/93 lessons0/23 achievements
0/100 XP to next level100 XP to go0% complete
"잡힌 값이 언제나 Error라는 보장은 없어. 먼저 무엇인지 확인하고, 그다음 처리해."

catch 변수는 왜 unknown인가

JavaScript에서는 throw 'oops'처럼 어떤 값이든 던질 수 있어. 그래서 useUnknownInCatchVariables가 켜진 catch (error)의 타입은 unknown이야. 곧바로 error.message를 읽지 말고 error instanceof Error 같은 좁히기를 거쳐야 해.

외부 라이브러리가 고유 오류 클래스를 제공한다면 그 클래스나 판별 가능한 속성을 확인할 수 있어. 단순한 타입 단언으로 Error라고 우기면 실제로 문자열이나 응답 객체가 왔을 때 또 다른 오류를 만들 뿐이야.

사용자 오류 클래스는 좁히기 정보를 더해

오류를 던질 때는 class NetworkError extends Error처럼 Error를 확장하고 상태 코드 같은 필드를 선언해. catch에서 instanceof NetworkError로 좁히면 스택과 메시지를 유지하면서 그 필드에도 안전하게 접근할 수 있어.

오류 처리는 catch 문법이 아니라 책임의 경계를 정하는 일이야. unknown에서 안전하게 좁히고, 이 계층이 실제로 복구할 수 있는 것만 처리해.

Code

Unknown 과 catch — 쓰기 전 narrow·typescript
// Unknown 과 catch — strict-mode default.
async function safeRun() {
  try {
    await riskyOp();
  } catch (e) {
    // e: unknown
    if (e instanceof Error) {
      console.error(e.message, e.stack);
    } else if (typeof e === 'string') {
      console.error('thrown string:', e);
    } else {
      console.error('thrown unknown value', e);
    }
  }
}

// 더 풍부한 narrowing 용 커스텀 error class.
class NetworkError extends Error {
  constructor(public readonly status: number, msg: string) {
    super(msg);
  }
}

async function fetchOrThrow(url: string) {
  const res = await fetch(url);
  if (!res.ok) throw new NetworkError(res.status, `Bad response: ${res.status}`);
  return res.json();
}

try {
  await fetchOrThrow('/users');
} catch (e) {
  if (e instanceof NetworkError) {
    console.error(`HTTP ${e.status}: ${e.message}`);
  } else {
    console.error('other error', e);
  }
}

External links

Exercise

비동기 함수를 실행해 성공 값을 반환하고, 던져진 값은 기록한 뒤 null로 바꾸는 safelyRun<T>을 작성해. Error와 그 밖의 값 모두 안전하게 좁혀.
Hint
catch의 값은 먼저 Error인지 확인해 기록해. 함수가 실패를 null로 바꾸기로 했다면 호출자도 그 null의 의미를 알고 처리해야 해.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.