fix: improve error handling for Twitter Jina fallback and invalid URL inputs
- Twitter _read_jina now detects unusable X.com responses (JS-required pages) and shows a friendly error instead of garbage HTML - CLI read command now shows user-friendly messages for invalid URLs and connection errors instead of raw HTTP exception traces
This commit is contained in:
@@ -62,6 +62,7 @@ class TwitterChannel(Channel):
|
|||||||
)
|
)
|
||||||
|
|
||||||
async def _read_jina(self, url: str) -> ReadResult:
|
async def _read_jina(self, url: str) -> ReadResult:
|
||||||
|
try:
|
||||||
resp = requests.get(
|
resp = requests.get(
|
||||||
f"https://r.jina.ai/{url}",
|
f"https://r.jina.ai/{url}",
|
||||||
headers={"Accept": "text/markdown"},
|
headers={"Accept": "text/markdown"},
|
||||||
@@ -69,14 +70,48 @@ class TwitterChannel(Channel):
|
|||||||
)
|
)
|
||||||
resp.raise_for_status()
|
resp.raise_for_status()
|
||||||
text = resp.text
|
text = resp.text
|
||||||
title = text[:100] if text else url
|
|
||||||
|
|
||||||
|
# Detect unusable Jina responses for X/Twitter (JS-required pages)
|
||||||
|
unusable_indicators = [
|
||||||
|
"this page doesn't exist",
|
||||||
|
"Don't miss what's happening",
|
||||||
|
"Something went wrong. Try reloading",
|
||||||
|
"Log in</a>",
|
||||||
|
]
|
||||||
|
if any(indicator in text for indicator in unusable_indicators):
|
||||||
|
return ReadResult(
|
||||||
|
title="Twitter/X",
|
||||||
|
content="⚠️ Could not read this tweet.\n"
|
||||||
|
"The tweet may have been deleted, or the account is private.\n\n"
|
||||||
|
"Tips:\n"
|
||||||
|
"- Make sure the URL is correct\n"
|
||||||
|
"- Try: birdx read <url> (if birdx is installed)\n"
|
||||||
|
"- For protected tweets, configure Twitter cookies: "
|
||||||
|
"agent-reach configure twitter-cookies AUTH_TOKEN CT0",
|
||||||
|
url=url,
|
||||||
|
platform="twitter",
|
||||||
|
)
|
||||||
|
|
||||||
|
title = text[:100] if text else url
|
||||||
return ReadResult(
|
return ReadResult(
|
||||||
title=title,
|
title=title,
|
||||||
content=text,
|
content=text,
|
||||||
url=url,
|
url=url,
|
||||||
platform="twitter",
|
platform="twitter",
|
||||||
)
|
)
|
||||||
|
except Exception:
|
||||||
|
return ReadResult(
|
||||||
|
title="Twitter/X",
|
||||||
|
content="⚠️ Could not read this tweet.\n"
|
||||||
|
"The tweet may have been deleted, or the account is private.\n\n"
|
||||||
|
"Tips:\n"
|
||||||
|
"- Make sure the URL is correct\n"
|
||||||
|
"- Try: birdx read <url> (if birdx is installed)\n"
|
||||||
|
"- For protected tweets, configure Twitter cookies: "
|
||||||
|
"agent-reach configure twitter-cookies AUTH_TOKEN CT0",
|
||||||
|
url=url,
|
||||||
|
platform="twitter",
|
||||||
|
)
|
||||||
|
|
||||||
async def search(self, query: str, config=None, **kwargs) -> List[SearchResult]:
|
async def search(self, query: str, config=None, **kwargs) -> List[SearchResult]:
|
||||||
limit = kwargs.get("limit", 10)
|
limit = kwargs.get("limit", 10)
|
||||||
|
|||||||
@@ -532,6 +532,14 @@ async def _cmd_read(args):
|
|||||||
print(f"👤 {result['author']}")
|
print(f"👤 {result['author']}")
|
||||||
print(f"\n{result.get('content', '')}")
|
print(f"\n{result.get('content', '')}")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
error_str = str(e)
|
||||||
|
if "400" in error_str and "Bad Request" in error_str:
|
||||||
|
print(f"❌ Invalid URL: {args.url}", file=sys.stderr)
|
||||||
|
print(" Please provide a valid URL (e.g., https://example.com)", file=sys.stderr)
|
||||||
|
elif "ConnectionError" in type(e).__name__ or "Timeout" in type(e).__name__:
|
||||||
|
print(f"❌ Could not connect to: {args.url}", file=sys.stderr)
|
||||||
|
print(" Check your internet connection or the URL.", file=sys.stderr)
|
||||||
|
else:
|
||||||
print(f"❌ Error: {e}", file=sys.stderr)
|
print(f"❌ Error: {e}", file=sys.stderr)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user