tonhowtf/omniget · error
Twitch GQL não respondeu depois de 5 tentativas: {}
Error message
Twitch GQL não respondeu depois de 5 tentativas: {} What it means
This error is raised after the Twitch GQL client exhausts its 5 retry attempts without receiving a successful response. On each attempt the client records the last failure reason (429 rate limit or server error) in `last`; when the loop ends it bails with that reason embedded. It means Twitch remained unavailable or rate-limited across all retries — a persistent transient failure, not a single bad request.
Solutions
- Add exponential backoff with jitter between retry attempts instead of retrying immediately.
- Inspect `last` in the message: if HTTP 429, slow down call rate, cache results, and respect Twitch rate limits.
- Route requests through a different IP/proxy if the current IP is persistently throttled.
- Increase the attempt count and/or add a longer cool-down for server errors (5xx) during Twitch outages.
- Surface the error to the caller with the recorded `last` status so users know it was a rate limit vs server error.
Example fix
// before
for _ in 0..5 {
// attempt request, on 429/5xx: last = ...; continue;
}
bail!("Twitch GQL não respondeu depois de 5 tentativas: {}", last)
// after
for attempt in 0..5 {
// attempt request...
tokio::time::sleep(Duration::from_millis(500 * 2u64.pow(attempt))).await;
}
bail!("Twitch GQL não respondeu depois de 5 tentativas: {}", last) Defensive patterns
Strategy: retry
Try / catch
match gql.query(&q).await {
Ok(v) => Ok(v),
Err(e) if e.to_string().contains("não respondeu depois de 5 tentativas") => {
tokio::time::sleep(Duration::from_secs(60)).await; // cool-down, then retry
gql.query(&q).await
}
Err(e) => Err(e),
} Prevention
- Throttle GQL call rate and cache responses to stay under Twitch's rate limits.
- Use exponential backoff with jitter in the retry loop.
- Avoid datacenter/VPN IPs that are aggressively rate-limited by Twitch.
- Monitor for HTTP 429 in the `last` status and pause the pipeline when it appears.
When it happens
Trigger: Any call through post (query or persisted query) where all 5 attempts return HTTP 429 or a 5xx status, so the retry loop never reaches the success path.
Common situations: Hammering Twitch's GQL endpoint without backoff and hitting sustained rate limits; Twitch GQL outage or maintenance window; IP-level throttling (datacenter/VPN IPs are heavily limited); misconfigured retry interval too short for the rate-limit window to reset.
Understand the failure class
Background: Request timed out: what client-side request timeouts mean across libraries (Request timed out, TIMED_OUT, APITimeoutError) — this error's family across 39 libraries.
Related errors
- o servidor está limitando o acesso (HTTP {}). Tente de novo
- o Reddit está limitando o acesso (HTTP {}). Tente de novo da
- {} respondeu HTTP {}
- Twitch GQL respondeu HTTP {}
- o servidor está limitando o acesso (HTTP {}). Tente de novo
AI-assisted analysis of tonhowtf/omniget@8600b91f42 (2026-09-12).
Data as JSON: /api/errors/19515f62f3d2ca4c.
Report an issue: GitHub.
Appendix: source
Thrown at src-tauri/omniget-core/src/core/tools/twitch/gql.rs:169
.await;
let resp = match sent {
Ok(r) => r,
Err(e) => {
last = e.to_string();
continue;
}
};
let status = resp.status();
if status.as_u16() == 429 || status.is_server_error() {
last = format!("HTTP {}", status);
continue;
}
if !status.is_success() {
bail!("Twitch GQL respondeu HTTP {}", status);
}
return Ok(resp.json::<Value>().await?);
}
bail!("Twitch GQL não respondeu depois de 5 tentativas: {}", last)
}
/// Query anônima em texto (as públicas aceitam sem persisted query).
pub async fn query(&self, query: &str) -> anyhow::Result<Value> {
let body = json!({ "query": query });
let json = self.post(&body).await?;
if let Some(msg) = first_error(&json) {
bail!("Twitch GQL: {}", msg);
}
json.get("data")
.cloned()
.ok_or_else(|| anyhow!("resposta do Twitch GQL sem `data`"))
}
/// Persisted query (formato em lote, como o site manda). Devolve o
/// primeiro elemento cru, para quem quiser ler `errors` também.
pub async fn persisted(&self, op: &str, hash: &str, vars: Value) -> anyhow::Result<Value> {
let body = json!([{View on GitHub (pinned to 8600b91f42)