feat(codebuddy): parse 6004 rate limit error and extract resetsAtMs

This commit is contained in:
ZIRAN456 authored and decolua committed 2026-09-28 12:36:10 +07:00
1 parent 57c04f00fa
commit e706e4f26a
3 files changed
+104

No files matched your search

+27
View File
@@ -64,6 +64,33 @@ export class CodeBuddyExecutor extends DefaultExecutor {
// filter and return an error (#2071). // filter and return an error (#2071).
return transformed; return transformed;
} }
parseError(response, bodyText) {
if (bodyText) {
try {
const data = JSON.parse(bodyText);
const msg = data?.msg || data?.message || data?.error?.message || "";
if (data?.code === 6004 || /超出频率限制|frequency limit|限额/i.test(msg)) {
let resetsAtMs = null;
const match = msg.match(/(\d{4}-\d{2}-\d{2})\s+(\d{2}:\d{2}:\d{2})(?:\s*UTC\+?([0-9:]+))?/i);
if (match) {
const dp = match[1];
const tp = match[2];
const tz = match[3]
? (match[3].includes(":") ? (match[3].startsWith("+") ? match[3] : `+${match[3]}`) : `+${match[3].padStart(2, "0")}:00`)
: "+08:00";
const dt = new Date(`${dp}T${tp}${tz}`);
if (!isNaN(dt.getTime())) resetsAtMs = dt.getTime();
}
return {
status: 429,
message: msg || "CodeBuddy frequency limit (6004)",
resetsAtMs,
};
}
} catch {}
}
return super.parseError(response, bodyText);
}
} }
export default CodeBuddyExecutor; export default CodeBuddyExecutor;
+27
View File
@@ -39,6 +39,33 @@ export class CodeBuddyIntlExecutor extends DefaultExecutor {
return transformed; return transformed;
} }
parseError(response, bodyText) {
if (bodyText) {
try {
const data = JSON.parse(bodyText);
const msg = data?.msg || data?.message || data?.error?.message || "";
if (data?.code === 6004 || /超出频率限制|frequency limit|限额/i.test(msg)) {
let resetsAtMs = null;
const match = msg.match(/(\d{4}-\d{2}-\d{2})\s+(\d{2}:\d{2}:\d{2})(?:\s*UTC\+?([0-9:]+))?/i);
if (match) {
const dp = match[1];
const tp = match[2];
const tz = match[3]
? (match[3].includes(":") ? (match[3].startsWith("+") ? match[3] : `+${match[3]}`) : `+${match[3].padStart(2, "0")}:00`)
: "+08:00";
const dt = new Date(`${dp}T${tp}${tz}`);
if (!isNaN(dt.getTime())) resetsAtMs = dt.getTime();
}
return {
status: 429,
message: msg || "CodeBuddy frequency limit (6004)",
resetsAtMs,
};
}
} catch {}
}
return super.parseError(response, bodyText);
}
} }
export default CodeBuddyIntlExecutor; export default CodeBuddyIntlExecutor;
+50
View File
@@ -0,0 +1,50 @@
import { describe, it, expect } from "vitest";
import { CodeBuddyExecutor } from "../../open-sse/executors/codebuddy-cn.js";
import { CodeBuddyIntlExecutor } from "../../open-sse/executors/codebuddy-intl.js";
describe("CodeBuddy parseError", () => {
it("parses code 6004 frequency limit with timestamp into 429 and resetsAtMs on codebuddy-cn", () => {
const executor = new CodeBuddyExecutor();
const bodyText = JSON.stringify({
code: 6004,
message: "当前模型超出频率限制,请于 2026-09-28 14:30:00 后重试",
});
const parsed = executor.parseError({ status: 200 }, bodyText);
expect(parsed.status).toBe(429);
expect(parsed.message).toContain("超出频率限制");
expect(parsed.resetsAtMs).toBeTruthy();
expect(typeof parsed.resetsAtMs).toBe("number");
// 验证时区解析 (默认 UTC+8)
const expected = new Date("2026-09-28T14:30:00+08:00").getTime();
expect(parsed.resetsAtMs).toBe(expected);
});
it("parses frequency limit text match without code 6004 on codebuddy-intl", () => {
const executor = new CodeBuddyIntlExecutor();
const bodyText = JSON.stringify({
code: 11000,
msg: "frequency limit exceeded, please retry after 2026-09-28 12:00:00 UTC+0",
});
const parsed = executor.parseError({ status: 400 }, bodyText);
expect(parsed.status).toBe(429);
expect(parsed.message).toContain("frequency limit");
const expected = new Date("2026-09-28T12:00:00+00:00").getTime();
expect(parsed.resetsAtMs).toBe(expected);
});
it("falls back to super.parseError for unrelated errors", () => {
const executor = new CodeBuddyExecutor();
const bodyText = JSON.stringify({
code: 11101,
message: "Non-stream chat request is currently not supported",
});
const parsed = executor.parseError({ status: 400 }, bodyText);
expect(parsed.status).toBe(400);
expect(parsed.message).toBe(bodyText);
expect(parsed.resetsAtMs).toBeUndefined();
});
});