fix: clean up HTML error messages in CLI display (#3069)

When API calls fail with HTML error pages (e.g., CloudFlare errors), the CLI
was dumping raw HTML content to users like:
  📝 Error: <!DOCTYPE html><!--[if lt IE 7]> <html class="no-js ie6...

This commit adds a _clean_error_message() utility method that:
- Detects HTML content and replaces with user-friendly message
- Collapses multiline errors to single line
- Truncates overly long errors (>150 chars)
- Preserves meaningful error text for regular errors

Applied to all user-facing error displays:
- API call failure messages (line 6314)
- Interrupt error responses (line 6324)
- Invalid response error messages (line 6000)

Before: 📝 Error: <!DOCTYPE html><!--[if lt IE 7]>...
After:  📝 Error: Service temporarily unavailable (HTML error page returned)
This commit is contained in:
Teknium
2026-03-25 16:39:22 -07:00
committed by GitHub
parent 9792bde31a
commit bd6b138e85

View File

@@ -1814,6 +1814,32 @@ class AIAgent:
return "***"
return f"{key[:8]}...{key[-4:]}"
def _clean_error_message(self, error_msg: str) -> str:
"""
Clean up error messages for user display, removing HTML content and truncating.
Args:
error_msg: Raw error message from API or exception
Returns:
Clean, user-friendly error message
"""
if not error_msg:
return "Unknown error"
# Remove HTML content (common with CloudFlare and gateway error pages)
if error_msg.strip().startswith('<!DOCTYPE html') or '<html' in error_msg:
return "Service temporarily unavailable (HTML error page returned)"
# Remove newlines and excessive whitespace
cleaned = ' '.join(error_msg.split())
# Truncate if too long
if len(cleaned) > 150:
cleaned = cleaned[:150] + "..."
return cleaned
def _dump_api_request_debug(
self,
api_kwargs: Dict[str, Any],
@@ -6033,7 +6059,8 @@ class AIAgent:
self._vprint(f"{self.log_prefix}⚠️ Invalid API response (attempt {retry_count}/{max_retries}): {', '.join(error_details)}", force=True)
self._vprint(f"{self.log_prefix} 🏢 Provider: {provider_name}", force=True)
self._vprint(f"{self.log_prefix} 📝 Provider message: {error_msg[:200]}", force=True)
cleaned_provider_error = self._clean_error_message(error_msg)
self._vprint(f"{self.log_prefix} 📝 Provider message: {cleaned_provider_error}", force=True)
self._vprint(f"{self.log_prefix} ⏱️ Response time: {api_duration:.2f}s (fast response often indicates rate limiting)", force=True)
if retry_count >= max_retries:
@@ -6347,7 +6374,8 @@ class AIAgent:
self._vprint(f"{self.log_prefix}⚠️ API call failed (attempt {retry_count}/{max_retries}): {error_type}", force=True)
self._vprint(f"{self.log_prefix} 🔌 Provider: {_provider} Model: {_model}", force=True)
self._vprint(f"{self.log_prefix} 🌐 Endpoint: {_base}", force=True)
self._vprint(f"{self.log_prefix} 📝 Error: {str(api_error)[:200]}", force=True)
cleaned_error = self._clean_error_message(str(api_error))
self._vprint(f"{self.log_prefix} 📝 Error: {cleaned_error}", force=True)
self._vprint(f"{self.log_prefix} ⏱️ Elapsed: {elapsed_time:.2f}s Context: {len(api_messages)} msgs, ~{approx_tokens:,} tokens")
# Check for interrupt before deciding to retry
@@ -6356,7 +6384,7 @@ class AIAgent:
self._persist_session(messages, conversation_history)
self.clear_interrupt()
return {
"final_response": f"Operation interrupted: handling API error ({error_type}: {str(api_error)[:80]}).",
"final_response": f"Operation interrupted: handling API error ({error_type}: {self._clean_error_message(str(api_error))}).",
"messages": messages,
"api_calls": api_call_count,
"completed": False,