{"record":{"id":"03c81be41448c7af","repo":"tonhowtf/omniget","slug":"twitter-api-retornou-http-mod","errorCode":null,"errorMessage":"Twitter API retornou HTTP {}","messagePattern":"Twitter API retornou HTTP (.+?)","errorType":"http","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"src-tauri/src/platforms/twitter/mod.rs","lineNumber":372,"sourceCode":"        }\n\n        let response = request.send().await?;\n\n        let status = response.status();\n        tracing::debug!(\"[twitter] graphql tweet_id={} status={}\", tweet_id, status);\n\n        if status == reqwest::StatusCode::FORBIDDEN\n            || status == reqwest::StatusCode::TOO_MANY_REQUESTS\n        {\n            return Err(anyhow!(\"token_expired\"));\n        }\n\n        if status == reqwest::StatusCode::NOT_FOUND {\n            return Err(anyhow!(\"Post not available\"));\n        }\n\n        if !status.is_success() {\n            return Err(anyhow!(\"Twitter API retornou HTTP {}\", status));\n        }\n\n        response.json().await.map_err(Into::into)\n    }\n\n    fn calculate_syndication_token(id: &str) -> String {\n        let num: f64 = id.parse().unwrap_or(0.0);\n        let raw = (num / 1e15) * std::f64::consts::PI;\n        let base36 = Self::f64_to_base36(raw);\n        base36\n            .replace('.', \"\")\n            .trim_start_matches('0')\n            .trim_end_matches('0')\n            .to_string()\n    }\n\n    fn f64_to_base36(value: f64) -> String {\n        if value == 0.0 {","sourceCodeStart":354,"sourceCodeEnd":390,"githubUrl":"https://github.com/tonhowtf/omniget/blob/8600b91f4246848bac346874daa9e61c1fc5677a/src-tauri/src/platforms/twitter/mod.rs#L354-L390","documentation":"request_tweet raises this formatted error when the GraphQL response status is neither 403/429, 404, nor a success — i.e. any other non-2xx HTTP status (5xx, 401, redirects, etc.). It surfaces the raw status code for diagnosis.","triggerScenarios":"Twitter's GraphQL endpoint returns e.g. 401 Unauthorized, 500/502/503/504 server errors, 301/302 redirects, or 400 Bad Request for a malformed variables/query_id combination.","commonSituations":"Outdated GraphQL query_id after a Twitter deploy (400); Twitter incident causing 5xx; missing/expired headers yielding 401; corporate proxy injecting its own error status.","solutions":["Read the logged status: 5xx → retry with backoff; 400 → refresh the GraphQL query_id/features from the current twitter.com bundle","Retry transient 5xx/timeout errors a limited number of times","Keep the hardcoded query_id and feature flags up to date — Twitter rotates them regularly","Check for proxy/firewall interference if unexpected statuses (30x/40x) appear consistently"],"exampleFix":"// before\nif !status.is_success() {\n    return Err(anyhow!(\"Twitter API retornou HTTP {}\", status));\n}\n// after\nif !status.is_success() {\n    return Err(anyhow!(\"Twitter API retornou HTTP {} body={}\", status,\n        response.text().await.unwrap_or_default()));\n}","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"match request_tweet(id).await {\n    Err(e) if e.to_string().starts_with(\"Twitter API retornou HTTP 5\") => {\n        tokio::time::sleep(backoff).await;\n        request_tweet(id).await\n    }\n    Err(e) if e.to_string().contains(\"400\") => {\n        platform.refresh_query_id().await?;\n        request_tweet(id).await\n    }\n    other => other,\n}","preventionTips":["Keep the GraphQL query_id and features current — Twitter rotates them","Implement exponential backoff for 5xx responses","Log the status code and response body on every non-success","Alert on repeated unexpected statuses to catch Twitter API changes fast"],"tags":["http","twitter","http-status","api"],"backgroundTag":"http-non-2xx-response","analyzedSha":"8600b91f4246848bac346874daa9e61c1fc5677a","analyzedAt":"2026-09-12T14:29:19.317Z","contentChangedAt":"2026-09-12T14:29:19.317Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}