{"record":{"id":"9b851f41ca3f1c52","repo":"tonhowtf/omniget","slug":"nenhuma-imagem","errorCode":null,"errorMessage":"nenhuma imagem","messagePattern":"nenhuma imagem","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src-tauri/omniget-core/src/core/tools/jpeg_pdf.rs","lineNumber":58,"sourceCode":"            return Ok(JpegInfo {\n                width,\n                height,\n                components,\n            });\n        }\n        i += 2 + len;\n    }\n    Err(anyhow!(\"JPEG sem cabecalho SOF\"))\n}\n\npub fn is_jpeg(data: &[u8]) -> bool {\n    data.len() > 3 && data[0] == 0xFF && data[1] == 0xD8 && data[2] == 0xFF\n}\n\n/// Monta o PDF em memória. Página no tamanho da imagem em pontos (72 dpi).\npub fn build_pdf(images: &[Vec<u8>]) -> anyhow::Result<Vec<u8>> {\n    if images.is_empty() {\n        return Err(anyhow!(\"nenhuma imagem\"));\n    }\n    let mut out: Vec<u8> = Vec::new();\n    let mut offsets: Vec<usize> = Vec::new();\n    out.extend_from_slice(b\"%PDF-1.4\\n%\\xE2\\xE3\\xCF\\xD3\\n\");\n\n    // objetos: 1 catalog, 2 pages, depois por imagem: page, xobject, content\n    let n_pages = images.len();\n    let obj_page = |i: usize| 3 + i * 3;\n    let obj_img = |i: usize| 4 + i * 3;\n    let obj_content = |i: usize| 5 + i * 3;\n    let total_objs = 2 + n_pages * 3;\n\n    let push_obj = |out: &mut Vec<u8>, offsets: &mut Vec<usize>, body: &[u8]| {\n        offsets.push(out.len());\n        out.extend_from_slice(body);\n    };\n\n    push_obj(","sourceCodeStart":40,"sourceCodeEnd":76,"githubUrl":"https://github.com/tonhowtf/omniget/blob/8600b91f4246848bac346874daa9e61c1fc5677a/src-tauri/omniget-core/src/core/tools/jpeg_pdf.rs#L40-L76","documentation":"build_pdf assembles an in-memory PDF from a slice of raw JPEG buffers, one page per image. With an empty input it has nothing to render, so it fails fast with \"nenhuma imagem\" (no images). It guards against generating a meaningless empty PDF.","triggerScenarios":"Calling build_pdf(&[]) — typically when an upstream collection step produced no images: a search/download returned zero results, or all files were filtered out as non-JPEG before reaching the builder.","commonSituations":"User confirms a PDF export with an empty selection; downloads all failed so the images vector ended up empty; caller filtered out corrupt/non-JPEG files leaving zero valid entries.","solutions":["Check images.len() > 0 before calling build_pdf and surface a friendly message to the user instead","Fix the upstream collection step (search/download) so at least one image is produced","Relax over-aggressive filtering that removes every candidate image before building"],"exampleFix":"// before\nlet images: Vec<Vec<u8>> = collect().into_iter().filter(valid).collect(); // empty\nlet pdf = build_pdf(&images)?; // Err: nenhuma imagem\n// after\nif images.is_empty() {\n    bail!(\"nenhuma imagem para converter\"); // handle before calling\n}\nlet pdf = build_pdf(&images)?;","handlingStrategy":"validation","validationCode":"if images.is_empty() {\n    return Err(\"nenhuma imagem para gerar o PDF\");\n}","typeGuard":"fn has_images(images: &[Vec<u8>]) -> bool {\n    !images.is_empty()\n}","tryCatchPattern":"match build_pdf(&images) {\n    Err(e) if e.to_string() == \"nenhuma imagem\" => show_empty_selection_warning(),\n    r => r,\n}","preventionTips":["Disable the PDF export action when the image list is empty","Check the upstream download/search step for zero results before building","Log how many candidate images survive filtering so silent empty sets are visible"],"tags":["pdf","empty-input","validation","rust"],"backgroundTag":"empty-result-set","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"}