概念
错误
错误使用标准的 HTTP 状态码,并且始终具有相同的 JSON 结构。
错误格式#
{
"error": {
"code": "INSUFFICIENT_SCOPE",
"message": "This API key does not have the scope posts:write"
}
}
code是稳定的:请在代码中使用它。message面向人类阅读,可能会变化。- 某些错误会在
code和message之外添加额外字段(例如校验错误中无效的字段)。
错误码#
| 状态码 | 错误码 | 含义 · 处理方法 |
|---|---|---|
| 400 | VALIDATION_ERROR | 某个参数或请求体字段缺失或无效。请修正请求;不要原样重试。 |
| 400 | INVALID_JSON | 请求体不是有效的 JSON。请发送 Content-Type: application/json 和有效的请求体。 |
| 401 | INVALID_API_KEY | 密钥缺失、格式错误或已被吊销。请检查 Authorization 请求头。 |
| 403 | INSUFFICIENT_SCOPE | 密钥缺少此端点所需的权限范围。请创建一个具有正确权限范围的密钥。 |
| 403 | DEVELOPER_ACCESS_REVOKED | 该账号的开发者权限已被暂停或撤销。请联系 developers@linework.app。 |
| 403 | PROFILE_INCOMPLETE | 使用写入类端点前,请先为账号添加头像和封面图。 |
| 403 | CHAT_NOT_ALLOWED | 反垃圾消息规则不允许发送此消息:对方没有给您发过消息,也没有关注您。 |
| 403 | CHAT_BLOCKED | 你们中有一方屏蔽了另一方。请勿重试。 |
| 403 | STORE_BLOCKED | 此店铺屏蔽了您。 |
| 403 | USER_UNAVAILABLE | 该用户不可用(已屏蔽、私密或已被停用)。 |
| 403 | FORBIDDEN | 此账号不允许执行该操作(例如编辑他人的帖子)。 |
| 404 | NOT_FOUND | 资源不存在,或您无权查看。 |
| 409 | CONFLICT | 请求与当前状态冲突(例如对同一订单发货两次)。 |
| 413 | PAYLOAD_TOO_LARGE | 请求体或上传的文件过大。请参阅发布带媒体的帖子中的媒体限制。 |
| 429 | RATE_LIMITED | 请求过多,或某项每日配额已用完。请等待 Retry-After 指定的时间。请参阅速率限制。 |
| 500 | INTERNAL_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')}")