duplicated body read fix

This commit is contained in:
2025-12-03 13:04:47 +01:00
parent 841d79f26b
commit a696c914ce
2 changed files with 6 additions and 4 deletions

View File

@@ -40,8 +40,10 @@ async function request<T = any>(method: string, url: string, body?: any, extraIn
}) })
if (!res.ok) { if (!res.ok) {
// Read the body once to avoid "Body has already been consumed" errors on non-JSON responses
const rawBody = await res.text().catch(() => '')
let details: any = undefined let details: any = undefined
try { details = await res.json() } catch { details = await res.text() } try { details = rawBody ? JSON.parse(rawBody) : undefined } catch { details = rawBody }
const status = res.status const status = res.status
if (status === 401) throw makeError('Unauthorized', 'UNAUTHORIZED', status, details) if (status === 401) throw makeError('Unauthorized', 'UNAUTHORIZED', status, details)
if (status === 403) throw makeError('Forbidden', 'FORBIDDEN', status, details) if (status === 403) throw makeError('Forbidden', 'FORBIDDEN', status, details)
@@ -114,4 +116,3 @@ export const chatbotApi = {
}).then(res => res.json()) }).then(res => res.json())
} }
} }

View File

@@ -19,8 +19,10 @@ export async function proxyRequest(path: string, init?: RequestInit): Promise<Re
export async function handleProxyResponse<T = any>(response: Response, defaultMessage = 'Request failed'): Promise<T> { export async function handleProxyResponse<T = any>(response: Response, defaultMessage = 'Request failed'): Promise<T> {
if (!response.ok) { if (!response.ok) {
// Read the body once to avoid "Body has already been consumed" when the upstream returns HTML errors
const rawBody = await response.text().catch(() => '')
let details: any let details: any
try { details = await response.json() } catch { details = await response.text() } try { details = rawBody ? JSON.parse(rawBody) : undefined } catch { details = rawBody }
throw new Error(typeof details === 'string' ? `${defaultMessage}: ${details}` : (details?.error || defaultMessage)) throw new Error(typeof details === 'string' ? `${defaultMessage}: ${details}` : (details?.error || defaultMessage))
} }
const contentType = response.headers.get('content-type') || '' const contentType = response.headers.get('content-type') || ''
@@ -28,4 +30,3 @@ export async function handleProxyResponse<T = any>(response: Response, defaultMe
// @ts-ignore allow non-json // @ts-ignore allow non-json
return (await response.text()) as T return (await response.text()) as T
} }