{"record":{"id":"be3901e24d9adf56","repo":"tonhowtf/omniget","slug":"http-ao-acessar-pin","errorCode":null,"errorMessage":"HTTP {} ao acessar pin {}","messagePattern":"HTTP (.+?) ao acessar pin (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src-tauri/omniget-core/src/platforms/pinterest.rs","lineNumber":109,"sourceCode":"            let canonical = redirect::resolve_redirect(&self.client, url).await?;\n            return Ok(canonical);\n        }\n        Ok(url.to_string())\n    }\n\n    async fn fetch_pin_html(&self, pin_id: &str) -> anyhow::Result<String> {\n        let url = format!(\"https://www.pinterest.com/pin/{}/\", pin_id);\n\n        let response = self\n            .client\n            .get(&url)\n            .header(\"Accept\", \"text/html\")\n            .header(\"Accept-Language\", \"en-US,en;q=0.9\")\n            .send()\n            .await?;\n\n        if !response.status().is_success() {\n            return Err(anyhow!(\n                \"HTTP {} ao acessar pin {}\",\n                response.status(),\n                pin_id\n            ));\n        }\n\n        response.text().await.map_err(Into::into)\n    }\n\n    fn check_pin_not_found(html: &str) -> bool {\n        PIN_NOT_FOUND_RE.is_match(html)\n    }\n\n    fn extract_video_url(html: &str) -> Option<String> {\n        VIDEO_URL_RE\n            .captures_iter(html)\n            .filter_map(|cap| cap.get(1).map(|m| m.as_str().to_string()))\n            .find(|url| url.ends_with(\".mp4\"))","sourceCodeStart":91,"sourceCodeEnd":127,"githubUrl":"https://github.com/tonhowtf/omniget/blob/8600b91f4246848bac346874daa9e61c1fc5677a/src-tauri/omniget-core/src/platforms/pinterest.rs#L91-L127","documentation":"fetch_pin_html() fetches the Pinterest pin page and checks response.status().is_success(); any non-2xx status aborts with 'HTTP <status> ao acessar pin <id>'. It surfaces the HTTP-level failure of scraping the pin's HTML so callers know the pin page could not be retrieved.","triggerScenarios":"Pinterest returns 404 (pin deleted/nonexistent), 403 (blocked scraper/region), 429 (rate limited), or 5xx while fetching the pin page for the extracted pin_id.","commonSituations":"Pin was removed or set private; Pinterest blocks requests lacking valid cookies/headers or from datacenter IPs; scraping too aggressively triggers rate limits; temporary Pinterest outages.","solutions":["Check the returned status: 404 means the pin is gone, stop retrying","On 403, use more browser-like headers or route via a residential proxy","On 429, back off and retry with exponential delay; throttle request rate","On 5xx, retry after a short delay; verify status on status.pinterest.com","Ensure the pin_id came from resolve_pin_url and is valid"],"exampleFix":"// before\nif !response.status().is_success() {\n    return Err(anyhow!(\"HTTP {} ao acessar pin {}\", response.status(), pin_id));\n}\n// after\nlet status = response.status();\nif status == reqwest::StatusCode::TOO_MANY_REQUESTS {\n    tokio::time::sleep(Duration::from_secs(30)).await;\n    return self.fetch_pin_html(&pin_id).await; // bounded retry\n}\nif !status.is_success() {\n    return Err(anyhow!(\"HTTP {} ao acessar pin {}\", status, pin_id));\n}","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"match fetch_pin_html(&pin_id).await {\n    Err(e) if e.to_string().contains(\"HTTP 429\") => {\n        tokio::time::sleep(Duration::from_secs(30)).await;\n        // bounded retry\n    }\n    Err(e) if e.to_string().contains(\"HTTP 404\") => return Err(anyhow!(\"pin is gone\")),\n    other => other?,\n}","preventionTips":["Throttle scrape rate and add exponential backoff on 429/5xx","Send browser-like headers (User-Agent, Accept, Accept-Language) as the code already does","Do not retry on 404/403 — fail fast and report to the user","Rotate egress IPs/proxies if scraping from datacenter ranges"],"tags":["http","scraping","pinterest","rate-limit","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"}