{"record":{"id":"9a3f0099f6211c03","repo":"tonhowtf/omniget","slug":"a-sa-da-do-gallery-dl-n-o-um-dump-json-v-lido","errorCode":null,"errorMessage":"a saída do gallery-dl não é um dump JSON válido","messagePattern":"a saída do gallery-dl não é um dump JSON válido","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src-tauri/omniget-core/src/core/tools/tumblr/gdl.rs","lineNumber":120,"sourceCode":"        return Ok(Vec::new());\n    }\n    if let Ok(Value::Array(items)) = serde_json::from_str::<Value>(trimmed) {\n        return Ok(items.iter().filter_map(entry_from).collect());\n    }\n    let mut out = Vec::new();\n    for line in trimmed.lines() {\n        let line = line.trim().trim_end_matches(',');\n        if line.is_empty() || line == \"[\" || line == \"]\" {\n            continue;\n        }\n        if let Ok(v) = serde_json::from_str::<Value>(line) {\n            if let Some(e) = entry_from(&v) {\n                out.push(e);\n            }\n        }\n    }\n    if out.is_empty() {\n        return Err(anyhow!(\"a saída do gallery-dl não é um dump JSON válido\"));\n    }\n    Ok(out)\n}\n\nfn entry_from(value: &Value) -> Option<Entry> {\n    let items = value.as_array()?;\n    let kind = items.first()?.as_u64()?;\n    match items.len() {\n        2 => Some(Entry {\n            kind,\n            url: None,\n            meta: items[1].clone(),\n        }),\n        3.. => Some(Entry {\n            kind,\n            url: items[1].as_str().map(|s| s.to_string()),\n            meta: items[2].clone(),\n        }),","sourceCodeStart":102,"sourceCodeEnd":138,"githubUrl":"https://github.com/tonhowtf/omniget/blob/8600b91f4246848bac346874daa9e61c1fc5677a/src-tauri/omniget-core/src/core/tools/tumblr/gdl.rs#L102-L138","documentation":"parse_dump parses gallery-dl JSON output and collects Entry objects; if no entry could be extracted from any top-level JSON value, it concludes the output is not a valid gallery-dl JSON dump and throws. This guards downstream code against operating on an empty or structurally unexpected document.","triggerScenarios":"gallery-dl -j returned JSON that is not an array of arrays/objects in the expected shape, or the command emitted valid JSON but with zero recognizable entries (e.g. an error object, null, or an empty array).","commonSituations":"gallery-dl version changed its JSON schema; URL is a page with no media so output is [] or an error JSON; gallery-dl printed a warning object instead of a dump; cookies are stale so the extractor returns an auth error payload.","solutions":["Run gallery-dl -j <url> manually and inspect the raw output shape","Update or pin gallery-dl to a version whose JSON dump matches the expected schema","Check gallery-dl's stderr/exit status upstream so error payloads are not fed to parse_dump","Confirm the URL has media (gallery not empty) before parsing"],"exampleFix":"// before\nlet text = stdout;\nlet entries = parse_dump(&text)?;\n// after\nlet text = stdout;\nif !status.success() || text.trim().is_empty() {\n    anyhow::bail!(\"gallery-dl falhou: {}\", stderr_tail);\n}\nlet entries = parse_dump(&text)?;","handlingStrategy":"try-catch","validationCode":"let parsed: Result<serde_json::Value, _> = serde_json::from_str(&text);\nif parsed.map_or(true, |v| v.as_array().map_or(true, |a| a.is_empty())) {\n    anyhow::bail!(\"gallery-dl não retornou entradas; verifique URL/cookies antes de parse_dump\");\n}","typeGuard":"fn is_valid_dump(v: &serde_json::Value) -> bool {\n    v.as_array().map_or(false, |a| !a.is_empty())\n}","tryCatchPattern":"match parse_dump(&text) {\n    Ok(entries) => entries,\n    Err(e) if e.to_string().contains(\"não é um dump JSON válido\") => {\n        eprintln!(\"stdout bruto: {}\", &text[..text.len().min(500)]);\n        return Err(e);\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Check gallery-dl exit status before parsing its stdout","Pin the gallery-dl version used in CI to avoid schema drift","Log the raw output whenever parsing fails"],"tags":["json","parsing","gallery-dl","unexpected-response"],"backgroundTag":"unexpected-response-shape","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"}