Skip to main content
SDK 提供两种错误类:用于 HTTP 与校验失败的 YoukaRequestError,以及用于以非成功状态结束的异步任务的 YoukaTaskError。两者都继承自 Error,并携带结构化字段,便于你根据 code、status 和是否可重试进行分支处理。

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;
  }
}

字段

code
string
机器可读的错误码,例如 INVALID_REQUESTUNAUTHORIZEDUPLOAD_FAILED
message
string
面向人的错误描述。
status
number
HTTP 状态码(如果可用)。
retryable
boolean
当 SDK 认为该错误值得重试时为 true(例如触发限流、短暂的服务器错误、幂等重放仍在进行中)。
details
unknown
由服务器提供的详情;对于校验错误,通常是 Zod 的 issue 列表。

常见 code

Code原因可重试?
INVALID_REQUEST请求体在发送前未通过 schema 校验。No
UNAUTHORIZED缺少或无效的 API key。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服务器返回的 body 与预期 schema 不匹配。No
UPLOAD_FAILEDSigned URL 上传返回非 2xx。取决于 status

YoukaTaskError

当底层 task 或 export 以 failedcancelledtimed-out 结束时,由 client.tasks.wait(...)client.projects.wait(...)client.exports.wait(...) 抛出。
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;
  }
}

字段

code
'TASK_FAILED' | 'TASK_CANCELLED' | 'TASK_TIMED_OUT'
直接映射到任务的终态状态。
message
string
服务器提供的任务错误信息,或生成的兜底信息。
status
TaskStatus
任务的终态状态。
task
RestTask
失败时刻的完整 task payload。适用于日志记录与面向用户的错误提示。

重试模式

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",
  }),
);
重试时务必复用同一个幂等键。否则服务器会将重试视为一次新请求,你可能会得到重复结果。

中止与取消

中止请求会抛出标准 AbortError —— 而不是 YoukaRequestError。请显式检查它:
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;
}

下一步