throwForHttpStatus function

Never throwForHttpStatus(
  1. int statusCode,
  2. String body,
  3. String providerName
)

Checks an HTTP status code and throws typed exceptions for known errors.

Call this in providers before the generic throw Exception(...) fallback.

Implementation

Never throwForHttpStatus(int statusCode, String body, String providerName) {
  if (statusCode == 401 || statusCode == 403) {
    throw AuthenticationException(
      '$providerName: Invalid or expired API key (HTTP $statusCode).',
    );
  }
  if (statusCode == 429) {
    // Try to parse Retry-After header value from the body (some providers
    // include it). Fall back to a default backoff.
    throw RateLimitException(
      '$providerName: Rate limited (HTTP 429). Slow down.',
    );
  }
  // Token/context overflow typically returns 400 with a specific message.
  final lowerBody = body.toLowerCase();
  if (statusCode == 400 &&
      (lowerBody.contains('context') ||
          lowerBody.contains('token') ||
          lowerBody.contains('too long') ||
          lowerBody.contains('maximum'))) {
    throw ContextOverflowException(
      '$providerName: Conversation too long for model context window.',
    );
  }
  if (statusCode == 529) {
    throw RateLimitException(
      '$providerName: API overloaded (HTTP $statusCode). Retry shortly.',
    );
  }
  // Server errors (5xx) — retryable.
  if (statusCode >= 500) {
    throw RateLimitException(
      '$providerName: Server error (HTTP $statusCode). Retry shortly.',
    );
  }
  throw Exception('$providerName API error (HTTP $statusCode): $body');
}