{"record":{"id":"8d6f4c450e98cce5","repo":"tonhowtf/omniget","slug":"tiktok-retornou-http","errorCode":null,"errorMessage":"TikTok retornou HTTP {}","messagePattern":"TikTok retornou HTTP (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src-tauri/omniget-core/src/platforms/tiktok.rs","lineNumber":144,"sourceCode":"        }\n        if !url.starts_with(\"http://\") && !url.starts_with(\"https://\") {\n            return false;\n        }\n        if url.contains(\"verify\") || url.contains(\"captcha\") {\n            return false;\n        }\n        true\n    }\n\n    async fn fetch_detail(&self, post_id: &str) -> anyhow::Result<serde_json::Value> {\n        let url = format!(\"https://www.tiktok.com/@i/video/{}\", post_id);\n\n        let response = self.client.get(&url).send().await?;\n\n        let status = response.status();\n\n        if !status.is_success() && status.as_u16() != 302 {\n            return Err(anyhow!(\"TikTok retornou HTTP {}\", status));\n        }\n\n        let mut cookie_parts = Vec::new();\n        for cookie in response.cookies() {\n            cookie_parts.push(format!(\"{}={}\", cookie.name(), cookie.value()));\n        }\n        if !cookie_parts.is_empty() {\n            let cookie_str = cookie_parts.join(\"; \");\n            *self.captured_cookies.lock().await = Some(cookie_str);\n        }\n\n        let html = response.text().await?;\n\n        if Self::is_captcha_page(&html) {\n            return Err(anyhow!(\n                \"TikTok is blocking requests. Try again in a few minutes.\"\n            ));\n        }","sourceCodeStart":126,"sourceCodeEnd":162,"githubUrl":"https://github.com/tonhowtf/omniget/blob/8600b91f4246848bac346874daa9e61c1fc5677a/src-tauri/omniget-core/src/platforms/tiktok.rs#L126-L162","documentation":"fetch_detail in tiktok.rs sends the detail request and, unless the status is a success code or 302 (deliberately allowed), converts it into this error containing the HTTP status. It surfaces non-2xx/302 responses from TikTok's detail endpoint as a library error, so the caller knows the request itself failed before HTML parsing.","triggerScenarios":"get_media_info -> fetch_detail where TikTok responds 403 (bot detection), 404 (video deleted/private), 429 (rate limited), or 5xx. Only 2xx and 302 pass through.","commonSituations":"Shared/deleted TikTok videos (404); aggressive rate limiting from repeated scraping (429); TikTok WAF blocking datacenter IPs (403); transient TikTok server errors (5xx).","solutions":["Read the embedded status: 404 means the video no longer exists; 403/429 mean throttling or bot detection","Add retry with backoff for 429/5xx responses","Rotate User-Agent/cookies or use a proxy if 403 persists","Check the URL points to an existing, public TikTok video"],"exampleFix":"// before\nreturn Err(anyhow!(\"TikTok retornou HTTP {}\", status));\n// after\nreturn Err(match status.as_u16() {\n    404 => anyhow!(\"TikTok video not found (HTTP 404)\"),\n    429 => anyhow!(\"TikTok rate limited (HTTP 429); retry later\"),\n    _ => anyhow!(\"TikTok retornou HTTP {}\", status),\n});","handlingStrategy":"retry","validationCode":"if (!(await tiktokVideoExists(url))) throw new Error(\"TikTok video unavailable or deleted\");","typeGuard":null,"tryCatchPattern":"match tiktok.get_media_info(url).await {\n    Err(e) if e.to_string().contains(\"TikTok retornou HTTP\") => {\n        let status = extract_status(&e);\n        match status {\n            404 => inform_user(\"Video deleted or private\"),\n            429 | 500..=599 => schedule_retry_with_backoff(),\n            403 => switch_proxy_or_cookies(),\n            _ => log_and_fail(e),\n        }\n    }\n    other => other?,\n}","preventionTips":["Throttle request rate and add jitter to avoid 429","Reuse captured cookies and a realistic browser User-Agent","Route through residential proxies if datacenter IPs get 403","Check video availability before automation runs"],"tags":["tiktok","http","scraping"],"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"}