{"record":{"id":"bb2445171478a74a","repo":"tonhowtf/omniget","slug":"x-http","errorCode":null,"errorMessage":"X {}: HTTP {} {}","messagePattern":"X (.+?): HTTP (.+?) (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src-tauri/omniget-core/src/core/tools/x/client.rs","lineNumber":314,"sourceCode":"        if status.as_u16() == 429 {\n            let reset = resp\n                .headers()\n                .get(\"x-rate-limit-reset\")\n                .and_then(|v| v.to_str().ok())\n                .and_then(|v| v.parse::<i64>().ok())\n                .map(|r| (r - chrono::Utc::now().timestamp()).max(1))\n                .unwrap_or(900);\n            return Err(anyhow!(\"X_RATE_LIMIT:{}\", reset));\n        }\n        let text = resp.text().await.unwrap_or_default();\n        if status.as_u16() == 404 {\n            return Ok(Err(\"not_found\".into()));\n        }\n        if status.as_u16() == 401 || status.as_u16() == 403 {\n            return Ok(Err(format!(\"auth:{}\", status.as_u16())));\n        }\n        if !status.is_success() {\n            return Err(anyhow!(\n                \"X {}: HTTP {} {}\",\n                op,\n                status,\n                text.chars().take(200).collect::<String>()\n            ));\n        }\n        let v: Value = serde_json::from_str(&text)\n            .map_err(|e| anyhow!(\"X {}: resposta invalida ({})\", op, e))?;\n        if v.get(\"data\")\n            .map(|d| d.is_null() || d.as_object().map(|o| o.is_empty()).unwrap_or(false))\n            .unwrap_or(true)\n        {\n            if let Some(msg) = v\n                .get(\"errors\")\n                .and_then(|e| e.as_array())\n                .and_then(|a| a.first())\n                .and_then(|e| e.get(\"message\"))\n                .and_then(|m| m.as_str())","sourceCodeStart":296,"sourceCodeEnd":332,"githubUrl":"https://github.com/tonhowtf/omniget/blob/8600b91f4246848bac346874daa9e61c1fc5677a/src-tauri/omniget-core/src/core/tools/x/client.rs#L296-L332","documentation":"Catch-all for non-success X API responses that are not 404 (treated as not_found) or 401/403 (treated as auth errors): the client errors with 'X <op>: HTTP <status> <first-200-chars-of-body>', giving the failing operation name plus a truncated body for diagnosis.","triggerScenarios":"check() receives statuses like 400, 404-as-unexpected, 5xx, or 429-adjacent errors outside the special-cased codes while executing a GraphQL op named in the message.","commonSituations":"X server errors (5xx) or maintenance; malformed query variables causing 400 Bad Request; deprecated GraphQL endpoints returning unexpected statuses after X API changes.","solutions":["Read the truncated body in the message — it usually names the exact problem (bad request field, blocked op).","Retry on 5xx with backoff; treat 400 as a bug in the query variables you pass.","Verify the GraphQL operation/queryId is current — X rotates these and stale ones fail.","Check X status/incident reports if 5xx persists across operations."],"exampleFix":"// before\nclient.gql_get(\"TweetDetail\", &vars).await?; // fails: X TweetDetail: HTTP 400 {\"errors\":...}\n// after\nlet v = client.gql_get(\"TweetDetail\", &vars).await\n    .map_err(|e| { tracing::error!(op = \"TweetDetail\", err = %e, \"x gql failed\"); e })?;","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"match client.gql_get(op, &q).await {\n    Err(e) if e.to_string().starts_with(\"X \") && e.to_string().contains(\"HTTP 5\") => {\n        backoff_retry(op, max_attempts = 3)\n    }\n    Err(e) => Err(e),\n    ok => ok,\n}","preventionTips":["Retry only transient statuses (5xx, 408) with exponential backoff.","Keep GraphQL operation IDs/queryIds up to date with X's current API.","Log the op name and truncated body included in the error for triage.","Validate request variables before sending to avoid 400s."],"tags":["x-api","http","upstream","graphql"],"backgroundTag":"upstream-api-error","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"}