{"record":{"id":"c893fcdb69e93517","repo":"tonhowtf/omniget","slug":"twitch-gql-respondeu-http","errorCode":null,"errorMessage":"Twitch GQL respondeu HTTP {}","messagePattern":"Twitch GQL respondeu HTTP (.+?)","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src-tauri/omniget-core/src/core/tools/twitch/gql.rs","lineNumber":165,"sourceCode":"                .header(\"Origin\", \"https://www.twitch.tv\")\n                .header(\"Referer\", \"https://www.twitch.tv/\")\n                .json(body)\n                .send()\n                .await;\n            let resp = match sent {\n                Ok(r) => r,\n                Err(e) => {\n                    last = e.to_string();\n                    continue;\n                }\n            };\n            let status = resp.status();\n            if status.as_u16() == 429 || status.is_server_error() {\n                last = format!(\"HTTP {}\", status);\n                continue;\n            }\n            if !status.is_success() {\n                bail!(\"Twitch GQL respondeu HTTP {}\", status);\n            }\n            return Ok(resp.json::<Value>().await?);\n        }\n        bail!(\"Twitch GQL não respondeu depois de 5 tentativas: {}\", last)\n    }\n\n    /// Query anônima em texto (as públicas aceitam sem persisted query).\n    pub async fn query(&self, query: &str) -> anyhow::Result<Value> {\n        let body = json!({ \"query\": query });\n        let json = self.post(&body).await?;\n        if let Some(msg) = first_error(&json) {\n            bail!(\"Twitch GQL: {}\", msg);\n        }\n        json.get(\"data\")\n            .cloned()\n            .ok_or_else(|| anyhow!(\"resposta do Twitch GQL sem `data`\"))\n    }\n","sourceCodeStart":147,"sourceCodeEnd":183,"githubUrl":"https://github.com/tonhowtf/omniget/blob/8600b91f4246848bac346874daa9e61c1fc5677a/src-tauri/omniget-core/src/core/tools/twitch/gql.rs#L147-L183","documentation":"The Twitch GQL client in omniget-core aborts with this error when the GraphQL endpoint returns a non-success, non-retryable HTTP status (anything not 429 and not a 5xx). The post helper retries transient failures (429 rate limits and server errors) up to 5 times, but treats other 4xx responses as permanent and bails immediately via anyhow. It signals that the request itself was rejected — typically bad query syntax, authentication issues, or an unexpected client error — rather than a transient outage.","triggerScenarios":"Calling GqlClient::post (directly or via query/persisted query helpers) with a request that Twitch answers with e.g. HTTP 400 (malformed query/variables), 401/403 (missing or invalid Client-Integrity or auth headers), or 404 (endpoint/operation no longer exists).","commonSituations":"Twitch changes its GQL schema or persisted-query hashes; missing Client-Integrity header now required by Twitch; malformed GraphQL variables built by the caller; corporate proxy or DNS interception returning 403/404; Twitch blocking anonymous queries from certain regions/ASNs.","solutions":["Log or print the full HTTP status and response body to identify which 4xx Twitch returned and why.","Verify the GraphQL query text and variables against Twitch's current public GQL schema (IntrospectionQuery or a playground).","Ensure required headers (Client-Id, Client-Integrity, OAuth token if the operation is not anonymous) are set on the request.","Update persisted-query hashes / operation names if Twitch rotated them.","If the status is 429 or 5xx, note this error path is not taken — rely on the existing retry loop and inspect the separate 'não respondeu depois de 5 tentativas' error instead."],"exampleFix":"// before\nif !status.is_success() {\n    bail!(\"Twitch GQL respondeu HTTP {}\", status);\n}\n// after\nif !status.is_success() {\n    let body = resp.text().await.unwrap_or_default();\n    bail!(\"Twitch GQL respondeu HTTP {}: {}\", status, body);\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"match gql.query(\"{ ... }\").await {\n    Ok(data) => handle(data),\n    Err(e) if e.to_string().contains(\"Twitch GQL respondeu HTTP\") => {\n        // non-retryable 4xx: log status, check auth headers/query syntax\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Keep Client-Id and Client-Integrity headers current with Twitch's requirements.","Validate GraphQL queries against the live Twitch schema before shipping them.","Distinguish permanent 4xx from retryable 429/5xx and only alert on the former.","Log the response body on non-success statuses to diagnose rejections quickly."],"tags":["network","http","twitch","graphql","api"],"backgroundTag":"http-error-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"}