{"record":{"id":"4e59b9c9665707c3","repo":"tonhowtf/omniget","slug":"ghostscript-n-o-gerou-nada","errorCode":null,"errorMessage":"ghostscript não gerou nada: {}","messagePattern":"ghostscript não gerou nada: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src-tauri/omniget-core/src/core/tools/pdf_repair.rs","lineNumber":431,"sourceCode":"\nasync fn open_pages(path: &str) -> Option<usize> {\n    let p = path.to_string();\n    tokio::task::spawn_blocking(move || super::pdf::info(&p, None).ok().map(|i| i.pages))\n        .await\n        .ok()\n        .flatten()\n}\n\nasync fn run_ghostscript(gs: &Path, input: &Path, output: &Path) -> anyhow::Result<()> {\n    let out = crate::core::process::command(gs)\n        .args([\"-q\", \"-dNOPAUSE\", \"-dBATCH\", \"-sDEVICE=pdfwrite\"])\n        .arg(format!(\"-sOutputFile={}\", output.display()))\n        .arg(input)\n        .output()\n        .await\n        .map_err(|e| anyhow!(\"ghostscript nao iniciou: {}\", e))?;\n    if !output.exists() || std::fs::metadata(output).map(|m| m.len()).unwrap_or(0) == 0 {\n        return Err(anyhow!(\n            \"ghostscript não gerou nada: {}\",\n            String::from_utf8_lossy(&out.stderr).trim()\n        ));\n    }\n    Ok(())\n}\n\nfn output_path(opts: &RepairOptions, inp: &Path) -> anyhow::Result<PathBuf> {\n    let dir = if opts.output_dir.trim().is_empty() {\n        inp.parent().map(|p| p.to_path_buf()).unwrap_or_default()\n    } else {\n        PathBuf::from(opts.output_dir.trim())\n    };\n    std::fs::create_dir_all(&dir)?;\n    let stem = inp\n        .file_stem()\n        .map(|s| s.to_string_lossy().to_string())\n        .unwrap_or_else(|| \"documento\".into());","sourceCodeStart":413,"sourceCodeEnd":449,"githubUrl":"https://github.com/tonhowtf/omniget/blob/8600b91f4246848bac346874daa9e61c1fc5677a/src-tauri/omniget-core/src/core/tools/pdf_repair.rs#L413-L449","documentation":"Thrown when the Ghostscript process ran to completion but the expected output PDF is missing or has zero bytes; the message embeds Ghostscript's stderr for diagnosis. It is a post-execution sanity check in run_ghostscript ensuring `-sOutputFile` actually produced a usable file.","triggerScenarios":"gs exits after writing nothing: input PDF is so corrupt pdfwrite fails; output directory/path not writable; output path overwritten by another concurrent run; gs erroring on an unsupported or encrypted input; disk full.","commonSituations":"Repairing a badly truncated PDF where pdfwrite bails out; running two repairs of the same input concurrently racing on the same `-reparado.pdf` output; read-only output directory; encrypted/password-protected PDF passed without handling; out-of-disk space.","solutions":["Read the stderr embedded in the error message — it contains Ghostscript's own diagnostic (e.g. 'Unrecoverable error', permission denied)","Try the \"rebuild\" repair mode, which reconstructs the PDF in pure Rust without Ghostscript","Check the input PDF opens elsewhere (e.g. `gs -dNOPAUSE -dBATCH -sDEVICE=nullpage input.pdf`) to confirm gs can parse it at all","Verify the output directory is writable and has free disk space; ensure no concurrent run targets the same output path","If the PDF is password-protected, unlock it before repair"],"exampleFix":"// before\npdf_repair::run(RepairOptions { mode: \"gs\".into(), inputs, ..Default::default() }, progress).await?;\n// after\nmatch pdf_repair::run(RepairOptions { mode: \"gs\".into(), inputs, ..Default::default() }, progress).await {\n    Ok(res) => res,\n    Err(e) if e.to_string().contains(\"não gerou nada\") =>\n        pdf_repair::run(RepairOptions { mode: \"rebuild\".into(), inputs, ..Default::default() }, progress).await?,\n    Err(e) => return Err(e),\n}","handlingStrategy":"try-catch","validationCode":"// Pre-check: can Ghostscript even read the input?\nlet probe = tokio::process::Command::new(&gs)\n    .args([\"-dNOPAUSE\",\"-dBATCH\",\"-sDEVICE=nullpage\"])\n    .arg(&input)\n    .output().await?;\nif !probe.status.success() { anyhow::bail!(\"gs não consegue ler a entrada: {}\", String::from_utf8_lossy(&probe.stderr)); }\n// Also ensure output dir is writable and has space\nlet dir = output.parent().unwrap_or(Path::new(\".\"));\nlet dir = dir.to_path_buf();\ntokio::fs::create_dir_all(&dir).await?;","typeGuard":"fn output_dir_writable(dir: &std::path::Path) -> bool {\n    let probe = dir.join(\".wtest\");\n    std::fs::write(&probe, b\"x\").is_ok() && std::fs::remove_file(&probe).is_ok()\n}","tryCatchPattern":"match run_ghostscript(&gs, &input, &output).await {\n    Ok(()) => {},\n    Err(e) if e.to_string().contains(\"não gerou nada\") => {\n        log::warn!(\"gs falhou: {e}; tentando modo rebuild\");\n        rebuild_pdf(&input, &output).await?;\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Log the embedded Ghostscript stderr — it names the real cause (unreadable input, encryption, disk)","Never run concurrent repairs that write the same output path; include the input stem/pid in output names","Unlock encrypted PDFs before gs repair","Check free disk space before large batch repairs"],"tags":["rust","ghostscript","pdf","external-process"],"backgroundTag":"empty-output-file","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"}