{"record":{"id":"078b564be4d04db6","repo":"tonhowtf/omniget","slug":"o-reddit-est-limitando-o-acesso-http-tente-de-novo-daqui-a","errorCode":null,"errorMessage":"o Reddit está limitando o acesso (HTTP {}). Tente de novo daqui a pouco","messagePattern":"o Reddit está limitando o acesso \\(HTTP (.+?)\\)\\. Tente de novo daqui a pouco","errorType":"http","errorClass":null,"httpStatus":429,"severity":"warning","filePath":"src-tauri/omniget-core/src/core/tools/reddit/mod.rs","lineNumber":434,"sourceCode":"        let mut wait = Duration::from_secs(3);\n        for attempt in 1..=TRIES {\n            self.pace().await;\n            self.requests.fetch_add(1, Ordering::Relaxed);\n            let resp = self.client.get(url).send().await;\n            match resp {\n                Ok(r) if r.status().as_u16() == 403 && attempt < TRIES => {\n                    let _ = r.text().await;\n                    self.unlock().await?;\n                }\n                Ok(r) if r.status().is_success() => {\n                    let text = r.text().await?;\n                    return serde_json::from_str(&text).map_err(|e| {\n                        anyhow!(\"o Reddit respondeu algo que não é JSON ({}): {}\", e, url)\n                    });\n                }\n                Ok(r) if r.status().as_u16() == 429 || r.status().is_server_error() => {\n                    if attempt == TRIES {\n                        return Err(anyhow!(\n                            \"o Reddit está limitando o acesso (HTTP {}). Tente de novo daqui a pouco\",\n                            r.status()\n                        ));\n                    }\n                    let retry = r\n                        .headers()\n                        .get(reqwest::header::RETRY_AFTER)\n                        .and_then(|v| v.to_str().ok())\n                        .and_then(|v| v.trim().parse::<u64>().ok())\n                        .map(Duration::from_secs);\n                    tokio::time::sleep(retry.unwrap_or(wait)).await;\n                    wait *= 2;\n                }\n                Ok(r) if r.status().as_u16() == 403 => {\n                    return Err(anyhow!(\n                        \"o Reddit barrou o acesso público (403). Costuma ser bloqueio de rede ou conteúdo restrito: tente de outra conexão\"\n                    ));\n                }","sourceCodeStart":416,"sourceCodeEnd":452,"githubUrl":"https://github.com/tonhowtf/omniget/blob/8600b91f4246848bac346874daa9e61c1fc5677a/src-tauri/omniget-core/src/core/tools/reddit/mod.rs#L416-L452","documentation":"`get_json` retries 429 (Too Many Requests) and 5xx responses with exponential backoff up to `TRIES` attempts. If the last attempt still returns 429 or a server error, it gives up and throws this message telling the user Reddit is rate limiting and to try again later. This is deliberate backoff exhaustion, not an unexpected failure.","triggerScenarios":"Making more `get_json` calls than Reddit's unauthenticated rate limit allows (roughly 10 req/min without OAuth); running many parallel requests from one IP; the retry loop exhausting all `TRIES` attempts while Reddit keeps returning 429 or 5xx.","commonSituations":"Bulk-scraping many posts/comments in a tight loop; a shared IP (office/VPN/proxy) already throttled by Reddit; Reddit incidents causing sustained 5xx responses.","solutions":["Wait several minutes before retrying — 429 windows reset over time","Add or increase delays between requests and reduce concurrency to 1","Authenticate with OAuth (client credentials) for a much higher rate limit","Respect the `Retry-After` header the code already parses instead of hammering","Switch network (different IP) if the address is shared and throttled"],"exampleFix":"// before\nfor id in ids {\n    let v = client.get_json(&post_url(id)).await?; // hammers the API\n}\n// after\nfor id in ids {\n    let v = loop {\n        match client.get_json(&post_url(id)).await {\n            Ok(v) => break v,\n            Err(e) if e.to_string().contains(\"limitando o acesso\") => {\n                tokio::time::sleep(Duration::from_secs(120)).await;\n            }\n            Err(e) => return Err(e),\n        }\n    };\n    tokio::time::sleep(Duration::from_secs(7)).await;\n}","handlingStrategy":"retry","validationCode":"// throttle proactively: never exceed ~1 request / 1.5s unauthenticated\nlet min_interval = Duration::from_millis(1500);\nif last_request.elapsed() < min_interval {\n    tokio::time::sleep(min_interval - last_request.elapsed()).await;\n}","typeGuard":null,"tryCatchPattern":"match client.get_json(url).await {\n    Ok(v) => v,\n    Err(e) if e.to_string().contains(\"limitando o acesso\") => {\n        tokio::time::sleep(Duration::from_secs(300)).await; // cool-down, then retry\n        client.get_json(url).await?\n    }\n    Err(e) => return Err(e.into()),\n}","preventionTips":["Serialize requests with a global rate limiter instead of firing concurrently","Respect the Retry-After header on 429 responses","Use OAuth authentication to raise the rate-limit ceiling","Add jittered exponential backoff around all Reddit calls","Monitor for 429 early and pause the whole job, not just one request"],"tags":["http","rate-limit","network","retry"],"backgroundTag":"rate-limit-exceeded","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"}