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

TypeScript 오류 클래스에 재시도 정책을 걸어

~12 min · errors, retries, discriminated

Level 0Observer
0 XP0/64 lessons0/13 achievements
0/150 XP to next level150 XP to go0% complete

상태 코드를 직접 해석하지 않아도 돼

SDK는 BadRequestError, AuthenticationError, PermissionDeniedError, NotFoundError, RateLimitError, InternalServerError, APIConnectionError 같은 구체 클래스를 내보내. instanceof로 분기하면 문자열이나 상태 코드 목록을 곳곳에 복사하지 않고도 책임과 대응을 구분할 수 있어.

자동 재시도는 클라이언트 성격에 맞춰

생성자의 maxRetries로 일반 호출의 429와 5xx 재시도 횟수를 정해. 기본값은 2야. 즉시 실패를 보여 줘야 하는 CLI는 작게, 오래 도는 배치 작업은 더 크게 둘 수 있어. 스트리밍과 부수 효과가 있는 호출에는 같은 값을 무심코 적용하지 마.

비싼 호출에는 멱등성 키를 붙여

호출별 옵션의 headers: { 'Idempotency-Key': key }로 키를 전달해. 네트워크가 흔들린 뒤 같은 요청을 다시 보내도 원래 결과를 재사용할 수 있어 이중 과금을 막아. 특히 긴 Opus 생성처럼 한 번의 비용이 큰 작업에서 의미가 커.

원칙: 구체 오류 클래스는 HTTP 분기를 컴파일러가 이해하는 정책 분기로 바꿔 줘. 그대로 활용해.

Code

Retry 자세 위한 instanceof 분기·typescript
import Anthropic, {
  BadRequestError,
  AuthenticationError,
  RateLimitError,
  InternalServerError,
  APIConnectionError,
} from '@anthropic-ai/sdk';

const client = new Anthropic({ maxRetries: 2 });

async function callOnce() {
  try {
    return await client.messages.create({
      model: 'claude-sonnet-4-6',
      max_tokens: 256,
      messages: [{ role: 'user', content: 'hi' }],
    });
  } catch (e) {
    if (e instanceof BadRequestError) throw e;             // 너 버그
    if (e instanceof AuthenticationError) throw e;          // ops 알림
    if (e instanceof RateLimitError) {
      const after = e.headers?.get('retry-after') ?? '2';
      await new Promise(r => setTimeout(r, Number(after) * 1000));
      return callOnce();
    }
    if (e instanceof InternalServerError || e instanceof APIConnectionError) {
      await new Promise(r => setTimeout(r, 2000));
      return callOnce();
    }
    throw e;
  }
}
비싼 호출에 idempotency key·typescript
const idempotencyKey = `claim-${claimId}-summary`;

const resp = await client.messages.create(
  {
    model: 'claude-opus-4-7',
    max_tokens: 4096,
    messages: [{ role: 'user', content: claimText }],
  },
  { headers: { 'Idempotency-Key': idempotencyKey } },
);

External links

Exercise

상태 코드로 분기하던 TypeScript 코드를 SDK가 내보낸 오류 클래스의 instanceof 검사로 바꿔. 각 클래스를 흉내 내 알맞은 재시도 정책을 고르는지 시험해.
Hint
BadRequestError가 이제 상위로 올라와 시험이 깨진다면, 삼키지 말고 요청 구조를 고쳐.

Progress

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

댓글 0

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

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