feat: Improve error messages when no models are available in rotation

- Add detailed error information including provider status
- Show cooldown remaining time for rate-limited providers
- Display failure counts for each provider
- Provide structured error response with rotation_id, attempted models, and details
parent 290892ae
...@@ -888,7 +888,45 @@ class RotationHandler: ...@@ -888,7 +888,45 @@ class RotationHandler:
if not available_models: if not available_models:
logger.error("No models available in rotation (all providers may be rate limited)") logger.error("No models available in rotation (all providers may be rate limited)")
logger.error("All providers in this rotation are currently deactivated") logger.error("All providers in this rotation are currently deactivated")
raise HTTPException(status_code=503, detail="No models available in rotation (all providers may be rate limited)")
# Build detailed error message with provider status information
error_details = []
error_details.append(f"No models available in rotation '{rotation_id}'")
error_details.append(f"Total providers in rotation: {len(providers)}")
error_details.append(f"Providers skipped (rate limited): {len(skipped_providers)}")
if skipped_providers:
error_details.append("Skipped providers:")
for provider_id in skipped_providers:
provider_config = self.config.get_provider(provider_id)
if provider_config:
error_tracking = config.error_tracking.get(provider_id, {})
disabled_until = error_tracking.get('disabled_until')
failures = error_tracking.get('failures', 0)
if disabled_until:
import time
cooldown_remaining = int(disabled_until - time.time())
if cooldown_remaining > 0:
error_details.append(f" - {provider_id}: Rate limited (cooldown: {cooldown_remaining}s remaining, failures: {failures})")
else:
error_details.append(f" - {provider_id}: Rate limited (cooldown expired, failures: {failures})")
else:
error_details.append(f" - {provider_id}: Rate limited (failures: {failures})")
else:
error_details.append(f" - {provider_id}: Not configured")
raise HTTPException(
status_code=503,
detail={
"message": "No models available in rotation (all providers may be rate limited)",
"rotation_id": rotation_id,
"total_providers": len(providers),
"skipped_providers": len(skipped_providers),
"skipped_provider_ids": skipped_providers,
"details": error_details
}
)
# Sort models by weight in descending order (higher weight = higher priority) # Sort models by weight in descending order (higher weight = higher priority)
available_models.sort(key=lambda m: m['weight'], reverse=True) available_models.sort(key=lambda m: m['weight'], reverse=True)
...@@ -1167,9 +1205,46 @@ class RotationHandler: ...@@ -1167,9 +1205,46 @@ class RotationHandler:
logger.error(f"Attempted {len(tried_models)} different model(s): {[m['name'] for m in tried_models]}") logger.error(f"Attempted {len(tried_models)} different model(s): {[m['name'] for m in tried_models]}")
logger.error(f"Last error: {last_error}") logger.error(f"Last error: {last_error}")
logger.error(f"Max retries ({max_retries}) reached without success") logger.error(f"Max retries ({max_retries}) reached without success")
# Build detailed error message
error_details = []
error_details.append(f"All providers in rotation '{rotation_id}' failed after {max_retries} attempts")
error_details.append(f"Attempted models: {[m['name'] for m in tried_models]}")
error_details.append(f"Last error: {last_error}")
# Add provider status information
error_details.append("Provider status:")
for provider in providers:
provider_id = provider['provider_id']
provider_config = self.config.get_provider(provider_id)
if provider_config:
error_tracking = config.error_tracking.get(provider_id, {})
disabled_until = error_tracking.get('disabled_until')
failures = error_tracking.get('failures', 0)
if disabled_until:
import time
cooldown_remaining = int(disabled_until - time.time())
if cooldown_remaining > 0:
error_details.append(f" - {provider_id}: Rate limited (cooldown: {cooldown_remaining}s remaining, failures: {failures})")
else:
error_details.append(f" - {provider_id}: Rate limited (cooldown expired, failures: {failures})")
else:
error_details.append(f" - {provider_id}: Available (failures: {failures})")
else:
error_details.append(f" - {provider_id}: Not configured")
raise HTTPException( raise HTTPException(
status_code=503, status_code=503,
detail=f"All providers in rotation failed after {max_retries} attempts. Last error: {last_error}" detail={
"message": f"All providers in rotation failed after {max_retries} attempts",
"rotation_id": rotation_id,
"attempted_models": [m['name'] for m in tried_models],
"attempted_count": len(tried_models),
"max_retries": max_retries,
"last_error": last_error,
"details": error_details
}
) )
def _create_streaming_response(self, response, provider_type: str, provider_id: str, model_name: str, handler, request_data: Dict, effective_context: int): def _create_streaming_response(self, response, provider_type: str, provider_id: str, model_name: str, handler, request_data: Dict, effective_context: int):
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment