refactor(x-media): share the HTTP-status error mapping

twitter, twitter auth and bsky carried the same 404/410 -> NotFound,
401/403 -> Blocked, else Transient block (comments included).
site::status_error holds it once. bilibili and misskey keep their own
matches: neither maps 404/410 and each has a status the others do not
(412 risk control, 400 + NO_SUCH_NOTE), so routing them through the shared
block would have reclassified those statuses for the user.
This commit is contained in:
2026-09-21 17:09:07 +08:00
parent b9dd1f4d08
commit 5630a86d88
4 changed files with 18 additions and 23 deletions
+1 -9
View File
@@ -130,15 +130,7 @@ pub async fn fetch(id: &str) -> Result<Tweet, FetchError> {
let status = response.status();
if !status.is_success() {
log::warn!("twitter auth fetch {id}: HTTP {status}");
return match status.as_u16() {
404 | 410 => Err(FetchError::NotFound),
// A stale/refused `auth_token` is not a bad moment: retrying it
// three times only delays the report.
401 | 403 => Err(FetchError::Blocked),
_ => Err(FetchError::Transient(format!(
"twitter auth status {status}"
))),
};
return Err(crate::site::status_error("twitter auth", status));
}
let text = response.text().await?;
let json: Value = serde_json::from_str(&text)?;
+1 -7
View File
@@ -103,13 +103,7 @@ pub async fn fetch(id: &str) -> Result<Tweet, FetchError> {
// 404/410 = gone (permanent); 429/5xx = transient and retried by fetch.
let status = response.status();
if !status.is_success() {
return match status.as_u16() {
404 | 410 => Err(FetchError::NotFound),
// A refusal or an auth demand is not a bad moment: retrying it
// three times only delays an error the user has to see.
401 | 403 => Err(FetchError::Blocked),
_ => Err(FetchError::Transient(format!("twitter status {status}"))),
};
return Err(crate::site::status_error("twitter", status));
}
let text = response.text().await?;
// Classify before building the tweet (see [`parse_syndication_body`]), and