| type JsonMap = Record<string, unknown>; | |
| function asJsonMap(value: unknown): JsonMap | null { | |
| if (!value || typeof value !== "object" || Array.isArray(value)) return null; | |
| return value as JsonMap; | |
| } | |
| export type ParsedApiBody = { | |
| data: JsonMap | null; | |
| text: string; | |
| }; | |
| export async function parseJsonOrText(response: Response): Promise<ParsedApiBody> { | |
| const text = await response.text().catch(() => ""); | |
| if (!text) return { data: null, text: "" }; | |
| try { | |
| const parsed = JSON.parse(text); | |
| return { data: asJsonMap(parsed), text }; | |
| } catch { | |
| return { data: null, text }; | |
| } | |
| } | |
| export function extractErrorMessage(parsed: ParsedApiBody, fallback: string): string { | |
| const detail = parsed.data?.detail; | |
| if (typeof detail === "string" && detail.trim()) return detail.trim(); | |
| const error = parsed.data?.error; | |
| if (typeof error === "string" && error.trim()) return error.trim(); | |
| if (parsed.text.trim()) return parsed.text.trim(); | |
| return fallback; | |
| } | |