(
response: Response,
fallbackMessage = 'Download failed',
)
| 182 | * error envelope on failure. Call this before reading `response.blob()`. |
| 183 | */ |
| 184 | export async function assertDownloadResponseOk( |
| 185 | response: Response, |
| 186 | fallbackMessage = 'Download failed', |
| 187 | ): Promise<void> { |
| 188 | const contentType = response.headers.get('content-type') ?? ''; |
| 189 | |
| 190 | if (contentType.includes('application/json')) { |
| 191 | let body: any; |
| 192 | try { |
| 193 | body = await response.json(); |
| 194 | } catch { |
| 195 | throw new ApiRequestError( |
| 196 | { code: 'PARSE_ERROR', message: fallbackMessage, retry: false }, |
| 197 | response.status, |
| 198 | ); |
| 199 | } |
| 200 | |
| 201 | if (body.status === 'error') { |
| 202 | if (body.error && typeof body.error === 'object' && body.error.code) { |
| 203 | throw new ApiRequestError(body.error as ApiError, response.status); |
| 204 | } |
| 205 | throw new ApiRequestError( |
| 206 | { code: 'MALFORMED_ERROR', message: fallbackMessage, retry: false }, |
| 207 | response.status, |
| 208 | ); |
| 209 | } |
| 210 | |
| 211 | if (!response.ok) { |
| 212 | throw new ApiRequestError( |
| 213 | { code: 'HTTP_ERROR', message: `HTTP ${response.status}`, retry: false }, |
| 214 | response.status, |
| 215 | ); |
| 216 | } |
| 217 | |
| 218 | throw new ApiRequestError( |
| 219 | { code: 'MALFORMED_DOWNLOAD_RESPONSE', message: fallbackMessage, retry: false }, |
| 220 | response.status, |
| 221 | ); |
| 222 | } |
| 223 | |
| 224 | if (!response.ok) { |
| 225 | throw new ApiRequestError( |
| 226 | { code: 'HTTP_ERROR', message: `HTTP ${response.status}`, retry: false }, |
| 227 | response.status, |
| 228 | ); |
| 229 | } |
| 230 | } |
| 231 | |
| 232 | /** |
| 233 | * Streaming (NDJSON) API request. |
no test coverage detected