( response: Response, body?: string, )
| 421 | * @returns The appropriate ComponentError subclass |
| 422 | */ |
| 423 | export function fromHttpResponse( |
| 424 | response: Response, |
| 425 | body?: string, |
| 426 | ): ComponentError { |
| 427 | const status = response.status; |
| 428 | const message = body || response.statusText || `HTTP ${status}`; |
| 429 | const details = { |
| 430 | url: response.url, |
| 431 | status, |
| 432 | statusText: response.statusText, |
| 433 | }; |
| 434 | |
| 435 | // Handle specific status codes |
| 436 | switch (status) { |
| 437 | // Rate limit - special handling for headers |
| 438 | case 429: |
| 439 | return RateLimitError.fromHeaders(response.headers, body); |
| 440 | |
| 441 | // Client errors (non-retryable) |
| 442 | case 400: |
| 443 | case 409: |
| 444 | case 422: |
| 445 | return new ValidationError(message, { details }); |
| 446 | |
| 447 | case 401: |
| 448 | return new AuthenticationError(message, { statusCode: status, details }); |
| 449 | |
| 450 | case 403: |
| 451 | return new PermissionError(message, { details }); |
| 452 | |
| 453 | case 404: |
| 454 | return new NotFoundError(message, { details }); |
| 455 | |
| 456 | case 408: |
| 457 | return new TimeoutError(message, 0, { details }); |
| 458 | |
| 459 | // Server errors (retryable) |
| 460 | case 500: |
| 461 | case 502: |
| 462 | case 503: |
| 463 | case 504: |
| 464 | return new ServiceError(message, { statusCode: status, details }); |
| 465 | |
| 466 | default: |
| 467 | // Unknown status code - classify as non-retryable HTTP error |
| 468 | // This preserves existing behavior for unexpected status codes |
| 469 | return new HttpError(message, status, { details }); |
| 470 | } |
| 471 | } |
| 472 | |
| 473 | /** |
| 474 | * Check if an error is a ComponentError |
no test coverage detected