{"record":{"id":"fce7fd2d5aa965d1","repo":"tonhowtf/omniget","slug":"escolha-a-pasta-de-destino-sound","errorCode":null,"errorMessage":"escolha a pasta de destino","messagePattern":"escolha a pasta de destino","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"src-tauri/omniget-core/src/core/tools/tiktok/sound.rs","lineNumber":290,"sourceCode":"}\n\n// ───────────────────────── execução ─────────────────────────\n\n/// Busca o objeto `music` na página do vídeo. Melhor esforço: qualquer\n/// tropeço devolve `None` e o crédito segue com o que o yt-dlp deu.\nasync fn fetch_music(client: &reqwest::Client, url: &str, pacer: &Pacer) -> Option<super::Music> {\n    pacer.wait().await;\n    let resp = client.get(url).send().await.ok()?;\n    if !resp.status().is_success() {\n        return None;\n    }\n    let html = resp.text().await.ok()?;\n    super::parse_music(&html)\n}\n\npub async fn run(opts: &Options, progress: ProgressFn) -> Result<SoundResult> {\n    if opts.dest.trim().is_empty() {\n        return Err(anyhow!(\"escolha a pasta de destino\"));\n    }\n    let dest = PathBuf::from(&opts.dest);\n    std::fs::create_dir_all(&dest)?;\n\n    let session = TempCookies::new(opts.session_netscape.as_deref());\n    let used_session = session.is_some();\n    let cookies: Option<PathBuf> = opts\n        .cookies\n        .as_deref()\n        .filter(|c| !c.trim().is_empty())\n        .map(PathBuf::from)\n        .or_else(|| session.path().map(|p| p.to_path_buf()));\n\n    let list_text = match opts.list_file.as_deref().filter(|p| !p.trim().is_empty()) {\n        Some(path) => std::fs::read_to_string(path)\n            .map_err(|e| anyhow!(\"não consegui ler a lista {}: {}\", path, e))?,\n        None => String::new(),\n    };","sourceCodeStart":272,"sourceCodeEnd":308,"githubUrl":"https://github.com/tonhowtf/omniget/blob/8600b91f4246848bac346874daa9e61c1fc5677a/src-tauri/omniget-core/src/core/tools/tiktok/sound.rs#L272-L308","documentation":"The TikTok sound downloader (sound::run) refuses to start when opts.dest is empty or whitespace-only. The destination folder is required because every extracted audio file is written under it (create_dir_all is called immediately after the check). The library throws this early, before any network work, so users get an immediate actionable message instead of a late IO failure.","triggerScenarios":"Calling run() with Options whose dest field is \"\", \"   \" or otherwise trims to empty; typically when the caller constructs Options programmatically without a folder or the UI passed no destination selection.","commonSituations":"Desktop/Tauri app user clicks download without picking a folder; config file or CLI argument missing --dest; a wrapper script builds Options with default empty strings for optional fields but dest is actually mandatory.","solutions":["Set opts.dest to a valid directory path before calling run()","Validate that dest.trim() is non-empty in the caller/UI before invoking run()","Fall back to a sensible default directory (e.g. downloads dir) when the user has not chosen one"],"exampleFix":"// before\nlet opts = Options { dest: String::new(), ..Default::default() };\nrun(&opts, progress).await?;\n// after\nlet opts = Options { dest: chosen_dir.unwrap_or_else(default_downloads_dir), ..Default::default() };\nassert!(!opts.dest.trim().is_empty());\nrun(&opts, progress).await?;","handlingStrategy":"validation","validationCode":"if opts.dest.trim().is_empty() {\n    return Err(anyhow!(\"dest é obrigatório: escolha a pasta de destino antes de chamar run()\"));\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always populate dest from a folder picker with a non-empty default","Validate all mandatory Options fields in a shared constructor"],"tags":["validation","missing-argument","rust","tauri"],"backgroundTag":"missing-required-argument","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"}