{"record":{"id":"373146146d51aed9","repo":"tonhowtf/omniget","slug":"o-goodreads-ainda-n-o-gerou-o-csv-depois-de-s-deixe","errorCode":null,"errorMessage":"o Goodreads ainda não gerou o CSV depois de {}s. Deixe goodreads.com/review/import aberto, espere e rode de novo — o link fica salvo lá","messagePattern":"o Goodreads ainda não gerou o CSV depois de (.+?)s\\. Deixe goodreads\\.com/review/import aberto, espere e rode de novo — o link fica salvo lá","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"src-tauri/omniget-core/src/core/tools/lists/goodreads.rs","lineNumber":307,"sourceCode":"            ));\n        }\n    }\n\n    // Espera: o CSV é gerado em segundo plano e responde 404 até ficar pronto.\n    let limit = Duration::from_secs(opts.wait_secs.clamp(30, 3600));\n    loop {\n        let code = f.head_status(&csv_url).await.unwrap_or(0);\n        if code == 200 {\n            break;\n        }\n        if code != 404 && code != 0 && code != 403 {\n            return Err(anyhow!(\n                \"o Goodreads respondeu HTTP {} no arquivo do export\",\n                code\n            ));\n        }\n        if started.elapsed() >= limit {\n            return Err(anyhow!(\n                \"o Goodreads ainda não gerou o CSV depois de {}s. Deixe goodreads.com/review/import aberto, espere e rode de novo — o link fica salvo lá\",\n                limit.as_secs()\n            ));\n        }\n        report(\n            p,\n            TOOL_ID,\n            \"progress\",\n            started.elapsed().as_secs(),\n            Some(limit.as_secs()),\n            Some(\"esperando o Goodreads gerar o CSV\".into()),\n        );\n        tokio::time::sleep(Duration::from_secs(10)).await;\n    }\n\n    let (bytes, _) = f.get_bytes(&csv_url).await?;\n    let csv = String::from_utf8_lossy(&bytes).to_string();\n    if !csv.to_lowercase().contains(\"title\") {","sourceCodeStart":289,"sourceCodeEnd":325,"githubUrl":"https://github.com/tonhowtf/omniget/blob/8600b91f4246848bac346874daa9e61c1fc5677a/src-tauri/omniget-core/src/core/tools/lists/goodreads.rs#L289-L325","documentation":"trigger_and_wait polls the CSV URL until the file is ready (HEAD 200). If the elapsed time exceeds the configured limit while the file is still 404/403/unreachable, it gives up with this message, noting that Goodreads generates exports asynchronously and the completed link is saved on the import page for later retrieval.","triggerScenarios":"The export generation did not complete within the polling timeout: a large library taking longer than `limit` to render, the POST trigger was accepted but Goodreads queued the job behind others, or the export never actually started.","commonSituations":"Very large Goodreads libraries (thousands of reviews) exceeding the default wait limit; running during Goodreads peak load; user closed the browser tab so the import page is not open to pick up the finished link later (though the link persists server-side).","solutions":["Leave goodreads.com/review/import open, wait several minutes to hours, then rerun — the finished export link is saved on that page and run() will reuse it without regenerating.","Rerun with the existing (non-forced) options: since an export was already requested, the ready link check will pick it up once generated.","Increase the polling timeout (limit) for very large libraries if the tool exposes it.","Do not trigger a new export while waiting — generating a new one deletes the in-progress/previous export."],"exampleFix":"// before\nrun(&f, &opts).await?; // timed out; large library\n\n// after\n// keep tab open, wait, then rerun non-forced:\n// curl -s https://www.goodreads.com/review/import | grep review_porter\nrun(&f, &Options { force: false, ..opts }).await?;","handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":"match run(&fetcher, &opts).await {\n    Err(e) if e.to_string().contains(\"ainda não gerou o CSV\") => {\n        eprintln!(\"Export still cooking; leave goodreads.com/review/import open and rerun later\");\n        schedule_rerun_in(Duration::from_secs(3600));\n    }\n    r => r?,\n}","preventionTips":["Run non-forced reruns later — the finished link is saved on the import page","Allow generous timeouts for large libraries","Never trigger a second export while waiting; it deletes the first"],"tags":["timeout","polling","goodreads","async-export"],"backgroundTag":"request-timeout","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"}