{"record":{"id":"3adff70ffcbf4184","repo":"tonhowtf/omniget","slug":"http-ao-acessar-pin-mod","errorCode":null,"errorMessage":"HTTP {} ao acessar pin {}","messagePattern":"HTTP (.+?) ao acessar pin (.+?)","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src-tauri/src/platforms/pinterest/mod.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/src/platforms/pinterest/mod.rs#L91-L127","documentation":"fetch_pin_html fetches a Pinterest pin page and rejects any non-2xx status with this Portuguese-language error embedding the HTTP status and pin ID. It means Pinterest's server responded but with an error status (404, 403, 429, 5xx), so the HTML cannot be parsed for media.","triggerScenarios":"native_get_media_info -> fetch_pin_html sends the GET request with browser-like headers and Pinterest returns a non-success status code for the pin page.","commonSituations":"Pin deleted or private (404/410); Pinterest blocking datacenter IPs or flagging the client (403); rate limiting (429); Pinterest outage (5xx); malformed pin URL that resolved to an error page.","solutions":["Log response.status() and pin_id; handle 404 separately as 'Pin not found' with a user-friendly message.","Add retry with exponential backoff for 429/5xx responses, honoring Retry-After headers.","Rotate user-agent / use residential proxy if 403 persists (Pinterest bot detection).","Validate the pin URL resolves to a real pin before fetching (use resolve_pin_url result)."],"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::NOT_FOUND {\n    anyhow::bail!(\"Pin not found: {}\", pin_id);\n}\nif !status.is_success() {\n    anyhow::bail!(\"HTTP {} ao acessar pin {} (pode ser bloqueio ou pin removido)\", status, pin_id);\n}","handlingStrategy":"retry","validationCode":"// Rust: pre-validate the pin URL shape before fetching HTML\nfn looks_like_pin_url(url: &str) -> bool {\n    url.contains(\"/pin/\") || url.starts_with(\"https://pin.it/\")\n}","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        fetch_pin_html(&pin_id).await // retry once after backoff\n    }\n    Err(e) if e.to_string().contains(\"HTTP 404\") => Err(anyhow!(\"Pin not found\")),\n    other => other,\n}","preventionTips":["Back off and honor Retry-After on 429s","Rotate user-agent and route through residential proxies for scale scraping","Distinguish 404 (pin gone) from 403/5xx (retryable) in error handling","Add integration tests that assert behavior on each status class"],"tags":["http","pinterest","scraping","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"}