Skip to content

Commit 90c7870

Browse files
fix(feishu): retry HTTP 429 and code 11232 for message send rate limits
Feishu Open API has three send-time rate limit signals: HTTP 429 (gateway-wide quota), business code 11232 (tenant-level message service: 100/min, 5/sec), and 230020 (per-chat). Previously only 230020 was retried; HTTP 429 and 11232 propagated as fatal errors. - Add 11232 to FEISHU_SEND_RATE_LIMIT_CODES. - In getFeishuSendRateLimitCode, recognize HTTP 429 before reading the body code so gateway-level limits enter the retry loop. - Update doc comment listing both gateway and business sources.
1 parent 1d0d226 commit 90c7870

1 file changed

Lines changed: 12 additions & 5 deletions

File tree

extensions/feishu/src/comment-shared.ts

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -90,22 +90,29 @@ export function createFeishuApiError(
9090

9191
// Feishu message-API error codes that signal a transient rate limit; safe to retry with backoff.
9292
// 230020: per-chat rate limit (ext=chat rate limit) — confirmed by real concurrent load test.
93+
// 11232: tenant-level "create message service trigger rate limit" (100/min, 5/sec per app/bot).
9394
// Distinct from FEISHU_BACKOFF_CODES in typing.ts, which covers the reaction API (99991400+).
94-
const FEISHU_SEND_RATE_LIMIT_CODES = new Set([230020]);
95+
const FEISHU_SEND_RATE_LIMIT_CODES = new Set([230020, 11232]);
9596
const FEISHU_SEND_MAX_RETRIES = 2;
9697
const FEISHU_SEND_RETRY_BASE_MS = 500;
9798

9899
/**
99-
* Returns the Feishu body error code when an AxiosError signals a retryable
100-
* message-API rate limit. The code lives in `error.response.data.code` on the
101-
* HTTP 400 response the Feishu API returns on frequency limit. Returns `undefined`
102-
* for all other errors.
100+
* Returns a numeric rate-limit signal when an AxiosError indicates a retryable
101+
* Feishu message-API rate limit. Sources, in priority order:
102+
* 1. Gateway-level HTTP 429 (app-wide quota; `x-ogw-ratelimit-reset` header)
103+
* 2. Business-level `code` in `error.response.data.code` matching
104+
* FEISHU_SEND_RATE_LIMIT_CODES (e.g. 230020 per-chat, 11232 tenant-level).
105+
* Returns `undefined` for all other errors so they propagate without retry.
103106
*/
104107
export function getFeishuSendRateLimitCode(error: unknown): number | undefined {
105108
if (!isRecord(error)) {
106109
return undefined;
107110
}
108111
const response = isRecord(error.response) ? error.response : undefined;
112+
// HTTP 429: Feishu Open API gateway-level rate limit, always retry.
113+
if (typeof response?.status === "number" && response.status === 429) {
114+
return 429;
115+
}
109116
const data = isRecord(response?.data) ? response.data : undefined;
110117
const code = data?.code;
111118
return typeof code === "number" && FEISHU_SEND_RATE_LIMIT_CODES.has(code) ? code : undefined;

0 commit comments

Comments
 (0)