{"record":{"id":"b2bce16339668801","repo":"tonhowtf/omniget","slug":"escolha-o-pdf-redact","errorCode":null,"errorMessage":"escolha o PDF","messagePattern":"escolha o PDF","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src-tauri/omniget-core/src/core/tools/pdf_redact.rs","lineNumber":835,"sourceCode":"        let (cx, cy, w) = *visible.get(i)?;\n        if any_inside(rects, cx, cy) {\n            Some(w.max(0.0))\n        } else {\n            None\n        }\n    };\n    let (mut new_ops, removed, _) = strip_glyphs(&ops, &is_two, &mut plan);\n    if bar {\n        new_ops.extend(bar_ops(rects, [0.0, 0.0, 0.0]));\n    }\n    set_content(doc, page_id, new_ops)?;\n    drop_annots(doc, page_id, rects);\n    Ok((true, removed, format!(\"{} caracteres apagados\", removed)))\n}\n\npub fn run(opts: &Options, progress: &super::ProgressFn) -> anyhow::Result<RedactResult> {\n    if opts.input.trim().is_empty() {\n        return Err(anyhow!(\"escolha o PDF\"));\n    }\n    let pw = if opts.password.is_empty() {\n        None\n    } else {\n        Some(opts.password.as_str())\n    };\n    let dpi = if opts.dpi == 0 { 150 } else { opts.dpi };\n    let quality = if opts.quality == 0 { 88 } else { opts.quality };\n\n    report(progress, \"progress\", 0, 4, Some(\"lendo o PDF\".into()));\n    let pages = pdf::read_raw_chars(&opts.input, pw, \"\")?;\n    let total_pages = pages.len();\n    let wanted = pdf::parse_ranges(&opts.pages, total_pages)?;\n    let (rects, terms_found) = plan_rects(&pages, opts, &wanted);\n    if rects.is_empty() {\n        return Err(anyhow!(\n            \"nada para tarjar: marque uma região ou digite um termo\"\n        ));","sourceCodeStart":817,"sourceCodeEnd":853,"githubUrl":"https://github.com/tonhowtf/omniget/blob/8600b91f4246848bac346874daa9e61c1fc5677a/src-tauri/omniget-core/src/core/tools/pdf_redact.rs#L817-L853","documentation":"Input validation at the entry of run(), the PDF redaction driver: when opts.input is empty or whitespace-only, the run aborts before opening any document. It is a generic guard on the user-supplied input path — it fires when the redaction operation is started without a PDF file chosen.","triggerScenarios":"Calling run(&opts, ...) with opts.input == \"\" or \"   \".","commonSituations":"UI invoked the redact command before a file was selected; Options constructed with the input field left unset; file path cleared between selection and run.","solutions":["Populate opts.input with the selected PDF path before calling run","Disable the redact action in the UI until a file is chosen","Validate input non-empty at the command boundary"],"exampleFix":"// before\nlet opts = Options { input: String::new(), .. };\nrun(&opts, &progress)?;\n// after\nif picked_path.is_empty() { bail!(\"select a PDF\"); }\nlet opts = Options { input: picked_path, .. };\nrun(&opts, &progress)?;","handlingStrategy":"validation","validationCode":"if opts.input.trim().is_empty() { bail!(\"select a PDF\"); }","typeGuard":"fn has_input(o: &Options) -> bool { !o.input.trim().is_empty() }","tryCatchPattern":null,"preventionTips":["Gate the redact button on a selected file","Trim paths at the boundary","Test with empty Options"],"tags":["pdf","validation","input"],"backgroundTag":"empty-required-field","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"}