(
error: unknown,
response: Response | undefined,
request: Request | undefined,
opts: { throwOnError?: boolean } | undefined,
)
| 11 | * `JSON.stringify(error)`, etc.) are byte-for-byte identical to before. |
| 12 | */ |
| 13 | export function wrapClientError( |
| 14 | error: unknown, |
| 15 | response: Response | undefined, |
| 16 | request: Request | undefined, |
| 17 | opts: { throwOnError?: boolean } | undefined, |
| 18 | ): unknown { |
| 19 | if (!opts?.throwOnError) return error |
| 20 | if (error instanceof Error) return error |
| 21 | |
| 22 | // NamedError-shaped responses (the common case for opencode 4xx) come |
| 23 | // through as POJOs — extract a useful message first, then wrap. |
| 24 | if (typeof error === "object" && error !== null && Object.keys(error).length > 0) { |
| 25 | const obj = error as { data?: { message?: unknown }; message?: unknown; name?: unknown } |
| 26 | const message = |
| 27 | (typeof obj.data?.message === "string" && obj.data.message) || |
| 28 | (typeof obj.message === "string" && obj.message) || |
| 29 | (typeof obj.name === "string" && obj.name) || |
| 30 | describe(request, response) |
| 31 | return new Error(message, { cause: { body: error, status: response?.status } }) |
| 32 | } |
| 33 | |
| 34 | if (typeof error === "string" && error.length > 0) { |
| 35 | return new Error(error, { cause: { body: error, status: response?.status } }) |
| 36 | } |
| 37 | |
| 38 | // Empty body / network failure / undefined / null / empty object. |
| 39 | const reason = response ? "(empty response body)" : "network error (no response)" |
| 40 | return new Error(`opencode server ${describe(request, response)}: ${reason}`, { |
| 41 | cause: { body: error, status: response?.status }, |
| 42 | }) |
| 43 | } |
| 44 | |
| 45 | function describe(request: Request | undefined, response: Response | undefined) { |
| 46 | const method = request?.method ?? "?" |
nothing calls this directly
no test coverage detected