Skip to main content
SDK는 두 가지 오류 클래스를 제공합니다: HTTP 및 검증 실패에는 YoukaRequestError, 비정상(성공이 아닌) 상태로 종료된 비동기 작업에는 YoukaTaskError를 사용합니다. 둘 다 Error를 확장하며, code, status, retryability로 분기할 수 있도록 구조화된 필드를 담고 있습니다.

YoukaRequestError

HTTP 오류, 요청 검증 실패, 그리고 잘못된 형식의 응답에 대해 발생합니다.
import { YoukaRequestError } from "@youka/sdk";

try {
  await client.projects.create(body);
} catch (error) {
  if (error instanceof YoukaRequestError) {
    console.error({
      code: error.code,
      message: error.message,
      status: error.status,
      retryable: error.retryable,
      details: error.details,
    });
  } else {
    throw error;
  }
}

Fields

code
string
기계가 읽을 수 있는 오류 코드입니다. 예: INVALID_REQUEST, UNAUTHORIZED, UPLOAD_FAILED.
message
string
사람이 읽을 수 있는 설명입니다.
status
number
가능하다면 HTTP 상태 코드입니다.
retryable
boolean
SDK가 해당 오류를 재시도할 가치가 있다고 판단하면 true입니다(요청 제한, 일시적인 서버 오류, 멱등 재실행 진행 중).
details
unknown
서버가 제공한 상세 정보입니다. 일반적으로 검증 오류의 경우 Zod 이슈 목록입니다.

Common codes

CodeCauseRetryable?
INVALID_REQUEST전송 전에 요청 본문이 스키마 검증에 실패했습니다.No
UNAUTHORIZEDAPI 키가 없거나 유효하지 않습니다.No
NOT_FOUND리소스가 존재하지 않거나 접근 권한이 없습니다.No
CONFLICT버전 충돌(HTTP 409).Yes
TOO_MANY_REQUESTS요청 제한에 걸렸습니다(HTTP 429).Yes
INTERNAL_SERVER_ERROR일시적인 서버 장애(HTTP 500).Yes
IDEMPOTENT_REPLAY_IN_PROGRESS동일한 멱등성 키로 원래 요청이 아직 실행 중입니다(HTTP 202).Yes
INVALID_RESPONSE서버가 예상 스키마와 일치하지 않는 본문을 반환했습니다.No
UPLOAD_FAILEDSigned URL 업로드가 2xx가 아닌 응답을 반환했습니다.Depends on status

YoukaTaskError

client.tasks.wait(...), client.projects.wait(...), client.exports.wait(...)에서, 기반이 되는 task 또는 export가 failed, cancelled, timed-out으로 종료되면 발생합니다.
import { YoukaTaskError } from "@youka/sdk";

try {
  await client.projects.wait(created);
} catch (error) {
  if (error instanceof YoukaTaskError) {
    console.error({
      code: error.code,
      message: error.message,
      status: error.status,
      task: error.task,
    });
  } else {
    throw error;
  }
}

Fields

code
'TASK_FAILED' | 'TASK_CANCELLED' | 'TASK_TIMED_OUT'
task의 종료 상태에 직접 매핑됩니다.
message
string
서버가 제공한 task 오류 메시지 또는 생성된 대체 메시지입니다.
status
TaskStatus
종료된 task 상태입니다.
task
RestTask
실패 시점의 전체 task 페이로드입니다. 로깅 및 사용자에게 보여줄 오류 메시지에 유용합니다.

Retry pattern

retryable을 멱등성 키와 함께 사용해 안전한 재시도 루프를 구성하세요:
import { YoukaRequestError } from "@youka/sdk";

async function createWithRetry<T>(fn: () => Promise<T>, maxAttempts = 3) {
  let lastError: unknown;

  for (let attempt = 1; attempt <= maxAttempts; attempt++) {
    try {
      return await fn();
    } catch (error) {
      lastError = error;
      if (
        error instanceof YoukaRequestError &&
        error.retryable &&
        attempt < maxAttempts
      ) {
        await new Promise((r) => setTimeout(r, 2 ** attempt * 1_000));
        continue;
      }
      throw error;
    }
  }

  throw lastError;
}

await createWithRetry(() =>
  client.projects.create(body, {
    idempotencyKey: "import-2026-04-08-song-001",
  }),
);
재시도 전반에 걸쳐 항상 동일한 멱등성 키를 재사용하세요. 그렇지 않으면 서버가 재시도를 새로운 요청으로 처리하며, 중복이 생길 수 있습니다.

Abort and cancellation

요청을 중단(abort)하면 YoukaRequestError가 아니라 표준 AbortError가 발생합니다. 명시적으로 확인하세요:
try {
  await client.projects.wait(created, { signal: controller.signal });
} catch (error) {
  if (error instanceof Error && error.name === "AbortError") {
    console.log("Cancelled by user");
    return;
  }
  throw error;
}

What’s next