Files
OmniRoute/src/lib/providers/validation/cozeError.ts
Diego Rodrigues de Sa e Souza 0adae00c7b Release v3.8.42 (#5459)
Release v3.8.42 — full CHANGELOG in CHANGELOG.md.

CI: 103 checks green incl. CodeQL (all languages), Semgrep, all 8 unit shards,
coverage, Node 24 compat, and integration tests. Full unit suite validated
locally: 19437 pass / 0 fail. The 3 red checks are advisory and do not gate
main (no required status checks): SonarCloud/SonarQube new-code coverage gate,
and PR Test Policy (test-masking detector flagging the legitimate dead-Phind
provider removal in #5530 — reviewed, correct).

Includes cycle-close reconciliation + repair of inherited base-red tests from
#5480/#5527/#5427/#5521 that the PR->release fast-path did not exercise.
2026-06-30 06:54:29 -03:00

57 lines
2.2 KiB
TypeScript

// #5426 — Coze surfaces key-validation failures as a JSON envelope shaped like
// `{ "code": 4100, "msg": "...", "logId": "...", "from": "bot-api" }`. Left
// untranslated, that raw envelope (logId included) leaks verbatim into the
// connection-validation UI. This pure helper recognizes the Coze shape and
// composes a friendly, leak-free message so callers can surface it instead of
// the raw body. Kept in its own leaf module (no network deps) so it is unit-
// testable in isolation.
function asRecord(value: unknown): Record<string, unknown> | null {
if (typeof value === "string") {
try {
const parsed = JSON.parse(value);
return parsed && typeof parsed === "object" && !Array.isArray(parsed)
? (parsed as Record<string, unknown>)
: null;
} catch {
return null;
}
}
return value && typeof value === "object" && !Array.isArray(value)
? (value as Record<string, unknown>)
: null;
}
/**
* When `body` looks like a Coze error envelope (a string `msg`, `from === "bot-api"`,
* or a `logId`), return a friendly one-line message composed from `msg`/`code`
* (e.g. `Coze rejected the key: <msg> (code <code>)`). Returns `null` for anything
* that is not a Coze envelope — including normal OpenAI-style errors, non-objects,
* empty objects, and non-JSON strings — so non-Coze callers fall through unchanged.
* Never echoes the raw `logId` or the whole body.
*/
export function extractCozeValidationError(body: unknown): string | null {
const record = asRecord(body);
if (!record) return null;
const msg = typeof record.msg === "string" ? record.msg.trim() : "";
const from = typeof record.from === "string" ? record.from : "";
const logId = typeof record.logId === "string" ? record.logId.trim() : "";
const looksLikeCoze = msg !== "" || from === "bot-api" || logId !== "";
if (!looksLikeCoze) return null;
const code = record.code;
const codeStr =
typeof code === "number"
? String(code)
: typeof code === "string" && code.trim() !== ""
? code.trim()
: "";
const detail = msg || "the API key was rejected";
return codeStr
? `Coze rejected the key: ${detail} (code ${codeStr})`
: `Coze rejected the key: ${detail}`;
}