C.W.K.
Stream
Lesson 05 of 05 · published

Error Handling: `catch (e: 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
"JavaScript 가 뭐든 throw 가능. TypeScript 가 catch 를 `unknown` 으로 타입해서 그 사실 처리하게."

Unknown catch parameter

JavaScript 가 `throw 'string'`, `throw 42`, `throw { custom: 'object' }`, `throw new Error(...)`, 또는 다른 값 허용. Catch block 이 도착한 어떤 모양이든 처리해야. Strict mode 의 `useUnknownInCatchVariables` flag (modern 프로젝트에 default 켜짐) 와 함께, catch parameter 의 타입이 `unknown`, property 접근 전 narrow 강제.

패턴: catch (e) { if (e instanceof Error) console.log(e.message); else console.error('unknown error', e); }. Narrowing 이 접근 안전하게.

왜 async 에 더 중요

Promise rejection 도 타입 안 붙음. fetch().then(...).catch(e => ...) — `e` 가 reject 된 어떤 거든, 뭐든 될 수. async/await 가 이걸 try/catch 로 데려오고, 거기서 unknown 규칙 발동. Strict mode 없으면 `e.message` 쓰고 string-throwing API 에 조용히 크래시.

더 풍부한 narrowing 용 커스텀 error class

Throw 할 때 Error 확장 선호: class NetworkError extends Error { constructor(public status: number) { super() } }. 그다음 `instanceof NetworkError` 로 narrow 해서 타입 붙은 필드 접근. Error 계층에 적용된 같은 이전 discriminated-union 패턴.

`e` 를 untrusted 입력으로 다뤄. JavaScript 의 유연성이 catch handler 가 접근 전 validate 해야 함 의미. instanceof 로 narrow, 모양에 분기, unknown 값에 graceful fallback.

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

fn 돌리고 결과 반환, 또는 throw 된 어떤 에러든 null 반환하는 safelyRun<T>(fn: () => Promise<T>): Promise<T | null> 함수 써. Error instance 와 다른 throw 된 값 둘 다 적절히 처리.
Hint
try { return await fn() } catch (e) { logError(e); return null }. logError 안에서 instanceof Error vs unknown 으로 narrow. 함수의 caller 가 null 이 '뭔가 잘못됨' 의미하는 거 알고 뭐인지 알 필요 없음.

Progress

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

댓글 0

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

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