{"record":{"id":"bf2d26265b91a947","repo":"tonhowtf/omniget","slug":"emotes","errorCode":null,"errorMessage":"{}","messagePattern":"\\{\\}","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src-tauri/omniget-core/src/core/tools/twitch/emotes.rs","lineNumber":839,"sourceCode":"                continue;\n            }\n        };\n        let status = resp.status();\n        if status.as_u16() == 429 || status.is_server_error() {\n            last = format!(\"HTTP {}\", status);\n            continue;\n        }\n        if !status.is_success() {\n            anyhow::bail!(\"HTTP {}\", status);\n        }\n        let bytes = resp.bytes().await?;\n        if bytes.is_empty() {\n            anyhow::bail!(\"arquivo vazio\");\n        }\n        std::fs::write(path, &bytes)?;\n        return Ok(());\n    }\n    Err(anyhow!(\"{}\", last))\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n\n    #[test]\n    fn le_emotes_e_badges_da_twitch() {\n        let user = json!({\n            \"subscriptionProducts\": [\n                { \"emotes\": [\n                    { \"id\": \"emotesv2_abc\", \"token\": \"xqcSlam\", \"assetType\": \"ANIMATED\" },\n                    { \"id\": \"305535174\", \"token\": \"xqcOmega\", \"assetType\": \"STATIC\" }\n                ]}\n            ],\n            \"broadcastBadges\": [\n                { \"setID\": \"subscriber\", \"version\": \"0\", \"title\": \"Subscriber\",\n                  \"imageURL\": \"https://static-cdn.jtvnw.net/badges/v1/abc/3\" }","sourceCodeStart":821,"sourceCodeEnd":857,"githubUrl":"https://github.com/tonhowtf/omniget/blob/8600b91f4246848bac346874daa9e61c1fc5677a/src-tauri/omniget-core/src/core/tools/twitch/emotes.rs#L821-L857","documentation":"fetch_one downloads a single emote image and, after retrying, throws with the message of the last failure ('{}' interpolates the final error). It is reached only when every attempt to produce a valid file failed, typically the raw last I/O or network error is surfaced verbatim.","triggerScenarios":"run() calling fetch_one for an emote whose download repeatedly failed (network error, 404 from a stale CDN URL) or whose std::fs::write to the output path failed (permission denied, no such directory) — the last attempt's error text becomes the message.","commonSituations":"Provider API returning dead/renamed emote URLs; output directory not existing or read-only filesystem; antivirus or permissions blocking the write; transient network drops exhausting retries.","solutions":["Read the interpolated message to see the underlying failure (network vs. fs::write)","Ensure the output directory exists and is writable before running","Retry — transient CDN/network failures often resolve","Verify the emote still exists on its provider (URL may be stale)"],"exampleFix":"// before\nstd::fs::create_dir_all(out_dir); // forgotten entirely\nlet set = fetch_all(...).await?;\n// after\nstd::fs::create_dir_all(out_dir)?;\nlet set = fetch_all(...).await?;","handlingStrategy":"try-catch","validationCode":"// Ensure the output directory exists and is writable before fetching.\nstd::fs::create_dir_all(out_dir)?;\nlet probe = out_dir.join(\".write-test\");\nstd::fs::write(&probe, b\"\")?;\nstd::fs::remove_file(&probe)?;","typeGuard":null,"tryCatchPattern":"match fetch_one(&emote, &path).await {\n    Err(e) if e.to_string().contains(\"arquivo vazio\") || e.is::<std::io::Error>() => {\n        tracing::warn!(\"emote {} failed, skipping: {}\", emote.name, e);\n    }\n    other => other?,\n}","preventionTips":["Create and verify the output directory before downloading","Retry once on transient network failures before giving up","Check provider URLs still resolve (stale CDN links 404)","Run with write permission to the target directory"],"tags":["twitch","emotes","download","io","retry"],"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"}