Spaces:
Paused
Paused
| /** | |
| * Normalize upstream error bodies to a JSON-safe payload. | |
| * Accepts unknown/object/string inputs and guarantees an { error: { ... } } shape. | |
| */ | |
| export function toJsonErrorPayload(rawError, fallbackMessage = "Upstream provider error") { | |
| const fallback = { | |
| error: { | |
| message: fallbackMessage, | |
| type: "upstream_error", | |
| code: "upstream_error", | |
| }, | |
| }; | |
| if (rawError && typeof rawError === "object") { | |
| const errorObj = rawError.error; | |
| if (typeof errorObj === "string") { | |
| return { | |
| error: { | |
| message: errorObj, | |
| type: "upstream_error", | |
| code: "upstream_error", | |
| }, | |
| }; | |
| } | |
| if (errorObj && typeof errorObj === "object") { | |
| const nestedMessage = extractErrorMessage(errorObj); | |
| if (!("message" in errorObj) && nestedMessage) { | |
| return { | |
| error: { | |
| ...errorObj, | |
| message: nestedMessage, | |
| type: errorObj.type || "upstream_error", | |
| code: errorObj.code || "upstream_error", | |
| }, | |
| }; | |
| } | |
| return rawError; | |
| } | |
| if (!("message" in rawError)) { | |
| const message = extractErrorMessage(rawError); | |
| if (message) { | |
| return { | |
| error: { | |
| message, | |
| type: rawError.type || "upstream_error", | |
| code: rawError.code || "upstream_error", | |
| details: rawError, | |
| }, | |
| }; | |
| } | |
| } | |
| return { error: rawError }; | |
| } | |
| if (typeof rawError === "string") { | |
| const trimmed = rawError.trim(); | |
| if (!trimmed) { | |
| return fallback; | |
| } | |
| try { | |
| const parsed = JSON.parse(trimmed); | |
| return toJsonErrorPayload(parsed, fallbackMessage); | |
| } catch { | |
| return { | |
| error: { | |
| message: trimmed, | |
| type: "upstream_error", | |
| code: "upstream_error", | |
| }, | |
| }; | |
| } | |
| } | |
| return fallback; | |
| } | |
| function extractErrorMessage(value) { | |
| if (!value || typeof value !== "object") return null; | |
| if (typeof value.message === "string" && value.message.trim()) { | |
| return value.message.trim(); | |
| } | |
| if (typeof value.detail === "string" && value.detail.trim()) { | |
| return value.detail.trim(); | |
| } | |
| if (Array.isArray(value.errors)) { | |
| const messages = value.errors | |
| .map((entry) => { | |
| if (typeof entry === "string") return entry.trim(); | |
| if (entry && typeof entry === "object") { | |
| return extractErrorMessage(entry) || JSON.stringify(entry); | |
| } | |
| return ""; | |
| }) | |
| .filter(Boolean); | |
| if (messages.length > 0) return messages.join(", "); | |
| } | |
| if (typeof value.name === "string" && value.name.trim()) { | |
| return value.name.trim(); | |
| } | |
| return null; | |
| } | |