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:
34
run_agent.py
34
run_agent.py
@@ -1814,6 +1814,32 @@ class AIAgent:
|
|||||||
return "***"
|
return "***"
|
||||||
return f"{key[:8]}...{key[-4:]}"
|
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(
|
def _dump_api_request_debug(
|
||||||
self,
|
self,
|
||||||
api_kwargs: Dict[str, Any],
|
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}⚠️ 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: {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)
|
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:
|
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}⚠️ 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} 🔌 Provider: {_provider} Model: {_model}", force=True)
|
||||||
self._vprint(f"{self.log_prefix} 🌐 Endpoint: {_base}", 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")
|
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
|
# Check for interrupt before deciding to retry
|
||||||
@@ -6356,7 +6384,7 @@ class AIAgent:
|
|||||||
self._persist_session(messages, conversation_history)
|
self._persist_session(messages, conversation_history)
|
||||||
self.clear_interrupt()
|
self.clear_interrupt()
|
||||||
return {
|
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,
|
"messages": messages,
|
||||||
"api_calls": api_call_count,
|
"api_calls": api_call_count,
|
||||||
"completed": False,
|
"completed": False,
|
||||||
|
|||||||
Reference in New Issue
Block a user