跳到正文
javinfo

错误处理

javinfo API 返回的 HTTP 状态码和错误响应体。

失败的请求不收费,只为 200 付费。

状态码

状态码含义
400请求有误。输入校验失败(缺参数、值超范围、枚举不对),/query 或 /idols 既没有 q 也没有筛选条件,或提供商 id 未知。
401缺少密钥或密钥无效。
402额度不足。Retry-After 为一小时,是给自动化客户端的提示;充值后立刻恢复。见计费。
404没有结果。由 /movie、/random、/idols/{id}、/discover/similar、/analytics/idols/* 的查找,以及 /resolve、/resolve/provenance、/resolve/streams 返回。
422仅 /query:没有提供商支持这种筛选/排序组合,固定的那个不支持,或没有 q 却翻过第 50 页。见筛选。
429请求太多:账户的每分钟上限,或实时提供商的小时额度。等满 Retry-After。
503用 providers= 固定的提供商超了小时额度。取消固定,或等满 Retry-After。
499客户端在提供商响应前关掉了请求。

/query 从不返回 404。没有匹配是正常的 200,带 count: 0 和空的 results 数组, 不收费 —— 看 count。命名查找(/idols/{id}、/discover/similar、resolve)在番号或 演员不存在时返回 404。

错误响应体

处理器的错误用 oRPC 信封,带 defined、code、status 和 message:

{
  "defined": false,
  "code": "NOT_FOUND",
  "status": 404,
  "message": "no title found for \"ZZZZ-99999\""
}

400 加 data.issues,每条失败规则一条:

{
  "defined": false,
  "code": "BAD_REQUEST",
  "status": 400,
  "message": "Input validation failed",
  "data": {
    "issues": [
      {
        "expected": "string",
        "code": "invalid_type",
        "path": ["q"],
        "message": "Invalid input: expected string, received undefined"
      }
    ]
  }
}

422:同样信封,status: 422,code: "BAD_REQUEST":

{
  "defined": false,
  "code": "BAD_REQUEST",
  "status": 422,
  "message": "does not support sort \"rating\""
}

网关拒绝、还没到处理器的,响应体更短:

{ "error": "invalid api key" }

完全没有密钥会通过网关,由处理器拒绝,返回 oRPC UNAUTHORIZED 响应体:

{
  "defined": false,
  "code": "UNAUTHORIZED",
  "status": 401,
  "message": "Unauthorized"
}

每分钟限流器也用短格式:{ "error": "rate limit exceeded" }。 别假设 code 一定存在 —— 按状态码分支,细节读响应体。

退避重试

429、402 和 503 带 Retry-After,单位秒。照着等:

if ([429, 402, 503].includes(res.status)) {
  const wait = Number(res.headers.get('Retry-After') ?? 1);
  await new Promise((r) => setTimeout(r, wait * 1000));
}

402 的一小时只是建议。有人在盯着就充值,马上重试。

本页内容