{"record":{"id":"d6b20e5c57531667","repo":"tonhowtf/omniget","slug":"o-pinterest-nao-devolveu-esse-pin","errorCode":null,"errorMessage":"o Pinterest nao devolveu esse pin","messagePattern":"o Pinterest nao devolveu esse pin","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src-tauri/omniget-core/src/core/tools/pinterest/api.rs","lineNumber":944,"sourceCode":"                .as_array()\n                .and_then(|a| a.first())\n                .and_then(|b| b.as_str())\n                .map(|b| b.to_string())\n                .or_else(|| rr[\"bookmark\"].as_str().map(|b| b.to_string()))\n                .filter(|b| b != \"-end-\" && !b.starts_with(\"Y2JOb25lO\"));\n            return Ok((rr[\"data\"].clone(), bookmark));\n        }\n    }\n\n    pub async fn pin(&self, id: &str) -> anyhow::Result<Pin> {\n        let (data, _) = self\n            .resource(\n                \"Pin\",\n                json!({ \"id\": id, \"field_set_key\": \"detailed\" }),\n                &format!(\"/pin/{}/\", id),\n            )\n            .await?;\n        parse_pin(&data).ok_or_else(|| anyhow!(\"o Pinterest nao devolveu esse pin\"))\n    }\n\n    pub async fn board(&self, user: &str, slug: &str) -> anyhow::Result<Board> {\n        let src = format!(\"/{}/{}/\", user, slug);\n        let (data, _) = self\n            .resource(\n                \"Board\",\n                json!({ \"username\": user, \"slug\": slug, \"field_set_key\": \"detailed\" }),\n                &src,\n            )\n            .await?;\n        parse_board(&data).ok_or_else(|| anyhow!(\"board nao encontrado\"))\n    }\n\n    pub async fn board_sections(&self, board_id: &str) -> anyhow::Result<Vec<Section>> {\n        let mut out = Vec::new();\n        let mut bookmark: Option<String> = None;\n        loop {","sourceCodeStart":926,"sourceCodeEnd":962,"githubUrl":"https://github.com/tonhowtf/omniget/blob/8600b91f4246848bac346874daa9e61c1fc5677a/src-tauri/omniget-core/src/core/tools/pinterest/api.rs#L926-L962","documentation":"api.rs fetches a pin via Pinterest's internal PinResource endpoint and parses the JSON into a Pin struct. When `parse_pin(&data)` returns None — i.e. the response lacked the fields expected for a \"detailed\" pin — the library raises this anyhow error instead of returning a partial object. It is the library's way of surfacing \"Pinterest answered, but the pin is not available\" (deleted, private, region-blocked, or anti-bot page returned).","triggerScenarios":"Calling PinterestApi::pin(id) when the id does not exist, was deleted, is in a secret/private board, or when Pinterest returns an HTML challenge/login page instead of PinResource JSON, making parse_pin fail.","commonSituations":"Stale pin ids saved in a database; scraping pins from another user's secret board; Pinterest serving unauthenticated/limited responses after rate limiting or cookie expiry.","solutions":["Verify the pin id (long numeric id) is still live by opening https://pinterest.com/pin/<id>/ in a browser.","Refresh/explicitly set session cookies on the client so Pinterest returns real JSON instead of a login page.","Add backoff/retry — transient anti-bot responses cause spurious parse failures.","Treat as not-found: catch the error and skip the pin rather than failing the whole batch."],"exampleFix":"// before\nlet pin = api.pin(&stale_id).await?;\n// after\nlet pin = match api.pin(&stale_id).await {\n    Ok(p) => p,\n    Err(e) if e.to_string().contains(\"nao devolveu\") => { skip(stale_id); continue; }\n    Err(e) => return Err(e),\n};","handlingStrategy":"try-catch","validationCode":"// Pin ids are long numeric strings\nfn is_plausible_pin_id(id: &str) -> bool { !id.is_empty() && id.chars().all(|c| c.is_ascii_digit()) && id.len() >= 10 }","typeGuard":"fn pin_is_fetchable(pin: &Option<Pin>) -> bool { pin.is_some() }","tryCatchPattern":"match api.pin(&id).await {\n    Ok(p) => process(p),\n    Err(e) if e.to_string().contains(\"nao devolveu esse pin\") => mark_deleted(&id),\n    Err(e) => return Err(e),\n}","preventionTips":["Validate pin ids are numeric before fetching","Keep session cookies fresh to avoid anti-bot pages","Retry transient failures with backoff before marking a pin dead","Treat individual pin failures as skippable in batch jobs"],"tags":["pinterest","parse-failure","not-found","scraping"],"backgroundTag":"entity-not-found","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"}