Linework Developers
ZH
获取权限

概念

错误

错误使用标准的 HTTP 状态码,并且始终具有相同的 JSON 结构。

错误格式#

{
  "error": {
    "code": "INSUFFICIENT_SCOPE",
    "message": "This API key does not have the scope posts:write"
  }
}
  • code 是稳定的:请在代码中使用它。
  • message 面向人类阅读,可能会变化。
  • 某些错误会在 code 和 message 之外添加额外字段(例如校验错误中无效的字段)。

错误码#

状态码错误码含义 · 处理方法
400VALIDATION_ERROR某个参数或请求体字段缺失或无效。请修正请求;不要原样重试。
400INVALID_JSON请求体不是有效的 JSON。请发送 Content-Type: application/json 和有效的请求体。
401INVALID_API_KEY密钥缺失、格式错误或已被吊销。请检查 Authorization 请求头。
403INSUFFICIENT_SCOPE密钥缺少此端点所需的权限范围。请创建一个具有正确权限范围的密钥。
403DEVELOPER_ACCESS_REVOKED该账号的开发者权限已被暂停或撤销。请联系 developers@linework.app。
403PROFILE_INCOMPLETE使用写入类端点前,请先为账号添加头像和封面图。
403CHAT_NOT_ALLOWED反垃圾消息规则不允许发送此消息:对方没有给您发过消息,也没有关注您。
403CHAT_BLOCKED你们中有一方屏蔽了另一方。请勿重试。
403STORE_BLOCKED此店铺屏蔽了您。
403USER_UNAVAILABLE该用户不可用(已屏蔽、私密或已被停用)。
403FORBIDDEN此账号不允许执行该操作(例如编辑他人的帖子)。
404NOT_FOUND资源不存在,或您无权查看。
409CONFLICT请求与当前状态冲突(例如对同一订单发货两次)。
413PAYLOAD_TOO_LARGE请求体或上传的文件过大。请参阅发布带媒体的帖子中的媒体限制。
429RATE_LIMITED请求过多,或某项每日配额已用完。请等待 Retry-After 指定的时间。请参阅速率限制。
500INTERNAL_ERROR我们这边出现了问题。请稍后使用退避策略重试。

今后可能会新增错误码:遇到未知错误码时,请按其 HTTP 状态码的通用含义处理。

是否重试?#

状态码重试?
400, 401, 403, 404, 409, 413否。请先修正请求、密钥或账号。
429是,在 Retry-After 之后。
500, 502, 503, 504是,使用指数退避。对于非幂等的写入操作(例如 POST /posts),请先确认该操作尚未执行。

错误处理示例#

const res = await fetch(url, options);
if (!res.ok) {
  const { error } = await res.json().catch(() => ({ error: { code: "UNKNOWN" } }));
  switch (error.code) {
    case "RATE_LIMITED": /* wait Retry-After, then retry */ break;
    case "INVALID_API_KEY":
    case "DEVELOPER_ACCESS_REVOKED": /* stop the bot and alert someone */ break;
    case "CHAT_NOT_ALLOWED": /* skip this user */ break;
    default: throw new Error(`${res.status} ${error.code}: ${error.message}`);
  }
}
r = s.post(url, json=body, timeout=30)  # s = requests.Session() with the Authorization header
if not r.ok:
    err = r.json().get("error", {})
    code = err.get("code")
    if code == "RATE_LIMITED":
        ...  # wait Retry-After, then retry
    elif code in ("INVALID_API_KEY", "DEVELOPER_ACCESS_REVOKED"):
        ...  # stop the bot and alert someone
    elif code == "CHAT_NOT_ALLOWED":
        ...  # skip this user
    else:
        raise RuntimeError(f"{r.status_code} {code}: {err.get('message')}")