tonhowtf/omniget · error · anyhow::Error

escolha a pasta de destino

Error message

escolha a pasta de destino

What it means

run() validates the export options before doing any work: if opts.dest is empty (or only whitespace), there is no output folder to write the exported Medium posts into, so it fails fast with this message. This is an up-front guard so the export never starts without a destination.

Solutions

  1. Set opts.dest to a valid existing (or creatable) folder path before calling run().
  2. Validate dest in the UI: disable the Export button and show a hint until a folder is chosen via the folder picker.
  3. On the caller side, guard with a check: if opts.dest.trim().is_empty() { prompt for folder } before invoking run().
  4. If dest comes from config, apply a default export directory when the field is empty.

Example fix

// before
let opts = Options { dest: String::new(), ..Default::default() };
run(&opts, progress).await?; // Err: escolha a pasta de destino
// after
let mut opts = Options { dest: String::new(), ..Default::default() };
if opts.dest.trim().is_empty() {
    opts.dest = folder_picker::pick("pasta de destino")?;
}
run(&opts, progress).await?;
Defensive patterns

Strategy: validation

Validate before calling

fn export_ready(opts: &Options) -> bool {
    !opts.dest.trim().is_empty() && (opts.markdown || opts.html || opts.json)
}

Try / catch

if let Err(e) = medium::run(&opts, progress).await {
    if e.to_string().contains("escolha a pasta de destino") {
        prompt_for_folder();
    } else {
        show_error(e);
    }
}

Prevention

When it happens

Trigger: Calling run(&opts, progress) with Options.dest set to "", " ", or never filled by the UI — the trimmed string is empty.

Common situations: User leaves the destination folder field blank and hits Export; a preset/profile restored with a missing dest key; calling the export programmatically without setting dest.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


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

Appendix: source

Thrown at src-tauri/omniget-core/src/core/tools/blogs/medium.rs:628

    let title = title.trim();
    if title.is_empty() {
        return md.to_string();
    }
    for prefix in ["## ", "# ", "### "] {
        let head = format!("{}{}", prefix, title);
        if let Some(rest) = md.strip_prefix(&head) {
            return rest.trim_start().to_string();
        }
    }
    md.to_string()
}

// ── Execução ───────────────────────────────────────────────────────────

pub async fn run(opts: &Options, progress: ProgressFn) -> Result<ExportResult> {
    let dest = opts.dest.trim();
    if dest.is_empty() {
        return Err(anyhow!("escolha a pasta de destino"));
    }
    if !opts.markdown && !opts.html && !opts.json {
        return Err(anyhow!("escolha ao menos um formato"));
    }
    let user = normalize_user(&opts.user);
    let root = PathBuf::from(dest);
    std::fs::create_dir_all(&root)?;

    let domains: Vec<String> = COOKIE_DOMAINS.iter().map(|d| d.to_string()).collect();
    let fetcher = Fetcher::new(opts.delay_ms, opts.session_netscape.as_deref(), &domains)?;

    let mut note: Option<String> = None;
    let mut source = "rss";
    let mut docs: Vec<PostDoc> = Vec::new();

    if fetcher.has_session() {
        match from_session(&fetcher, opts, &progress).await {
            Ok(d) => {

View on GitHub (pinned to 8600b91f42)