tonhowtf/omniget · error · anyhow::Error

escolha a pasta de destino

Error message

escolha a pasta de destino

What it means

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.

Solutions

  1. Set opts.dest to a valid directory path before calling run()
  2. Validate that dest.trim() is non-empty in the caller/UI before invoking run()
  3. Fall back to a sensible default directory (e.g. downloads dir) when the user has not chosen one

Example fix

// before
let opts = Options { dest: String::new(), ..Default::default() };
run(&opts, progress).await?;
// after
let opts = Options { dest: chosen_dir.unwrap_or_else(default_downloads_dir), ..Default::default() };
assert!(!opts.dest.trim().is_empty());
run(&opts, progress).await?;
Defensive patterns

Strategy: validation

Validate before calling

if opts.dest.trim().is_empty() {
    return Err(anyhow!("dest é obrigatório: escolha a pasta de destino antes de chamar run()"));
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


AI-assisted analysis of tonhowtf/omniget@8600b91f42 (2026-09-12). Data as JSON: /api/errors/fce7fd2d5aa965d1. Report an issue: GitHub.

Appendix: source

Thrown at src-tauri/omniget-core/src/core/tools/tiktok/sound.rs:290

}

// ───────────────────────── execução ─────────────────────────

/// Busca o objeto `music` na página do vídeo. Melhor esforço: qualquer
/// tropeço devolve `None` e o crédito segue com o que o yt-dlp deu.
async fn fetch_music(client: &reqwest::Client, url: &str, pacer: &Pacer) -> Option<super::Music> {
    pacer.wait().await;
    let resp = client.get(url).send().await.ok()?;
    if !resp.status().is_success() {
        return None;
    }
    let html = resp.text().await.ok()?;
    super::parse_music(&html)
}

pub async fn run(opts: &Options, progress: ProgressFn) -> Result<SoundResult> {
    if opts.dest.trim().is_empty() {
        return Err(anyhow!("escolha a pasta de destino"));
    }
    let dest = PathBuf::from(&opts.dest);
    std::fs::create_dir_all(&dest)?;

    let session = TempCookies::new(opts.session_netscape.as_deref());
    let used_session = session.is_some();
    let cookies: Option<PathBuf> = opts
        .cookies
        .as_deref()
        .filter(|c| !c.trim().is_empty())
        .map(PathBuf::from)
        .or_else(|| session.path().map(|p| p.to_path_buf()));

    let list_text = match opts.list_file.as_deref().filter(|p| !p.trim().is_empty()) {
        Some(path) => std::fs::read_to_string(path)
            .map_err(|e| anyhow!("não consegui ler a lista {}: {}", path, e))?,
        None => String::new(),
    };

View on GitHub (pinned to 8600b91f42)