{"record":{"id":"d982e7ec9148d373","repo":"tonhowtf/omniget","slug":"respondeu-http","errorCode":null,"errorMessage":"{} respondeu HTTP {}","messagePattern":"(.+?) respondeu HTTP (.+?)","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src-tauri/omniget-core/src/core/tools/twitch/emotes.rs","lineNumber":523,"sourceCode":"        ch = html_escape(channel),\n        n = items.len(),\n        cards = cards\n    )\n}\n\nfn html_escape(s: &str) -> String {\n    s.replace('&', \"&amp;\")\n        .replace('<', \"&lt;\")\n        .replace('>', \"&gt;\")\n        .replace('\"', \"&quot;\")\n}\n\n// ───────────────────────── coleta e download ─────────────────────────\n\nasync fn json_get(http: &reqwest::Client, url: &str) -> anyhow::Result<Value> {\n    let resp = http.get(url).send().await?;\n    if !resp.status().is_success() {\n        anyhow::bail!(\"{} respondeu HTTP {}\", url, resp.status());\n    }\n    Ok(resp.json::<Value>().await?)\n}\n\npub async fn run(opts: &Options, p: &ProgressFn) -> anyhow::Result<Result> {\n    let gql = Gql::new()?;\n    let http = super::super::client()?;\n\n    let login = if opts.channel.trim().is_empty() {\n        None\n    } else {\n        Some(\n            super::gql::parse_channel(&opts.channel)\n                .ok_or_else(|| anyhow!(\"não reconheci esse canal: {}\", opts.channel))?,\n        )\n    };\n\n    report(p, ID, \"progress\", 0, None, Some(\"lendo o canal\".into()));","sourceCodeStart":505,"sourceCodeEnd":541,"githubUrl":"https://github.com/tonhowtf/omniget/blob/8600b91f4246848bac346874daa9e61c1fc5677a/src-tauri/omniget-core/src/core/tools/twitch/emotes.rs#L505-L541","documentation":"json_get() in emotes.rs is a helper that GETs a URL and bails when the HTTP response status is not a success (2xx). It reports the URL and the exact status code. This is how the emote provider layer surfaces non-200 responses (404, 403, 429, 5xx) from upstream JSON APIs (Twitch GQL, 7TV, BTTV, FFZ endpoints).","triggerScenarios":"Calling run() or live_provedores_de_emote_respondem when any upstream emote-provider JSON endpoint returns a non-success status: expired/invalid Twitch auth for GQL, wrong or removed provider URL, rate limiting (429), or provider outage (5xx).","commonSituations":"Twitch requiring authentication for GQL client credentials; a provider API changing its endpoint path in a newer version; hammering the API and hitting 429; corporate proxy returning 403/502 HTML pages.","solutions":["Read the URL and status in the message; check the provider's status page and whether the endpoint moved.","Ensure valid Twitch credentials/GQL setup where the endpoint requires auth.","Add backoff/retry for 429/5xx responses before re-running.","Update the tool to the latest version so provider endpoint definitions are current."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// before calling run(), check network reachability of the provider endpoint:\nlet status = reqwest::get(\"https://7tv.io/v3/emote-sets/global\").await?.status();\nif !status.is_success() { eprintln!(\"provedor indisponível: {}\", status); }","typeGuard":null,"tryCatchPattern":"match emotes::run(&opts, &progress).await {\n    Err(e) if e.to_string().contains(\"respondeu HTTP 429\") => {\n        tokio::time::sleep(Duration::from_secs(30)).await;\n        emotes::run(&opts, &progress).await?;\n    }\n    other => other?,\n}","preventionTips":["Keep Twitch credentials valid and refreshed where GQL requires auth.","Throttle requests to respect provider rate limits.","Monitor provider status pages / changelogs for endpoint moves.","Retry with exponential backoff on 429 and 5xx statuses."],"tags":["twitch","emotes","http","network"],"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"}