{"record":{"id":"e1d4de52c86f8994","repo":"tonhowtf/omniget","slug":"nao-consegui-baixar-a-imagem","errorCode":null,"errorMessage":"nao consegui baixar a imagem ({})","messagePattern":"nao consegui baixar a imagem \\((.+?)\\)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src-tauri/omniget-core/src/core/tools/pinterest/media.rs","lineNumber":171,"sourceCode":"        if bytes.len() < 64 {\n            last = format!(\"resposta vazia em {}\", cand);\n            continue;\n        }\n        let ext = sniff_ext(&bytes).unwrap_or(if ct.contains(\"png\") {\n            \"png\"\n        } else if ct.contains(\"gif\") {\n            \"gif\"\n        } else if ct.contains(\"webp\") {\n            \"webp\"\n        } else {\n            \"jpg\"\n        });\n        if ext == \"mp4\" {\n            continue;\n        }\n        return Ok((bytes, ext));\n    }\n    Err(anyhow!(\"nao consegui baixar a imagem ({})\", last))\n}\n\nfn webp_to_png(bytes: &[u8]) -> anyhow::Result<Vec<u8>> {\n    let img = image::load_from_memory(bytes)?;\n    let mut out = std::io::Cursor::new(Vec::new());\n    img.write_to(&mut out, image::ImageFormat::Png)?;\n    Ok(out.into_inner())\n}\n\npub fn base_name(pin: &Pin, naming: &str) -> String {\n    let title = pin.title.trim();\n    let title = if title.is_empty() {\n        pin.alt_text.trim()\n    } else {\n        title\n    };\n    let short: String = title.chars().take(70).collect();\n    let clean = super::super::sanitize_name(&short);","sourceCodeStart":153,"sourceCodeEnd":189,"githubUrl":"https://github.com/tonhowtf/omniget/blob/8600b91f4246848bac346874daa9e61c1fc5677a/src-tauri/omniget-core/src/core/tools/pinterest/media.rs#L153-L189","documentation":"fetch_image() iterates the candidate image URLs of a pin, downloading each and skipping videos (mp4). If every candidate fails — all HTTP errors, empty bodies, or decode failures — it raises \"nao consegui baixar a imagem ({})\" with the last error/status (`last`). This is an aggregate failure after exhausting all image sources for the pin.","triggerScenarios":"Calling download_pin (which calls fetch_image) on a pin whose image URLs are expired CDN links (i.pinimg.com 403/404), behind a region block, or when the network/proxy blocks i.pinimg.com so every attempt fails.","commonSituations":"Old pins whose CDN originals were purged; scraping without Referer/User-Agent headers so Pinterest CDN returns 403; offline/proxied environments; saving to a disk already full if the last error is a write failure.","solutions":["Inspect the interpolated `last` error — it names the final HTTP status or IO failure.","Retry with backoff; CDN 403/429s are often transient or header-sensitive.","Ensure the HTTP client sends a browser-like User-Agent/Referer for i.pinimg.com.","Verify network/proxy access to i.pinimg.com (curl one image URL directly).","Skip the pin gracefully — thumbnails may still be fetchable from a smaller variant."],"exampleFix":"// before\nlet (bytes, ext) = fetch_image(&pin).await?;\n// after\nlet (bytes, ext) = fetch_image(&pin).await\n    .map_err(|e| { log::warn!(\"image download failed: {e}\"); e })\n    .unwrap_or_else(|_| (Vec::new(), \"missing\".into())); // or skip pin","handlingStrategy":"retry","validationCode":"// Cheap pre-flight: is the CDN reachable at all?\nlet ok = reqwest::get(\"https://i.pinimg.com/\").await.map(|r| r.status().is_success()).unwrap_or(false);\nanyhow::ensure!(ok, \"i.pinimg.com unreachable from this network\");","typeGuard":"null","tryCatchPattern":"let img = match fetch_image(&pin).await {\n    Ok(x) => x,\n    Err(e) if e.to_string().contains(\"403\") || e.to_string().contains(\"429\") => {\n        sleep(Duration::from_secs(5)).await;\n        fetch_image(&pin).await?\n    }\n    Err(e) => { skip_pin(&pin.id, e); return Ok(()); }\n};","preventionTips":["Read the trailing `last` error for the decisive status code","Send browser-like User-Agent/Referer headers to i.pinimg.com","Retry 403/429 with backoff before giving up","Fall back to smaller image variants when originals are purged"],"tags":["pinterest","http","download","cdn","image"],"backgroundTag":"http-request-failed","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"}