{"record":{"id":"3c9d0c5fe80da664","repo":"tonhowtf/omniget","slug":"a-sess-o-do-goodreads-n-o-est-v-lida-capture-os-cookies-de","errorCode":null,"errorMessage":"a sessão do Goodreads não está válida: capture os cookies de goodreads.com na extensão","messagePattern":"a sessão do Goodreads não está válida: capture os cookies de goodreads\\.com na extensão","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src-tauri/omniget-core/src/core/tools/lists/goodreads.rs","lineNumber":249,"sourceCode":"            let rest = &html[at + marker.len()..];\n            let id: String = rest.chars().take_while(|c| c.is_ascii_digit()).collect();\n            if !id.is_empty() {\n                return Some(id);\n            }\n        }\n    }\n    None\n}\n\n/// Dispara o export e espera o CSV aparecer. Devolve `(csv, segundos)`.\n///\n/// O caminho é o mesmo do navegador: pegar o token anti-CSRF da página de\n/// importação, mandar o POST em `/review_porter/export/<id>` e depois ficar\n/// perguntando pelo arquivo, que responde 404 enquanto não fica pronto.\nasync fn trigger_and_wait(f: &Fetcher, opts: &Options, p: &ProgressFn) -> Result<(String, u64)> {\n    let page = f.get_text(IMPORT_URL).await?;\n    if is_signed_out(&page) {\n        return Err(anyhow!(\n            \"a sessão do Goodreads não está válida: capture os cookies de goodreads.com na extensão\"\n        ));\n    }\n    let uid = user_id(&page).ok_or_else(|| {\n        anyhow!(\"não achei o id da sua conta na página de importação do Goodreads\")\n    })?;\n    let csv_url = export_csv_url(&uid);\n\n    // Se já existe um export pronto, aproveita: o Goodreads só deixa gerar um\n    // a cada poucos dias, e gerar um novo apaga o anterior.\n    let ready = !opts.force && export_link(&page).is_some();\n    let started = Instant::now();\n    if !ready {\n        let token = csrf_token(&page).ok_or_else(|| {\n            anyhow!(\n                \"não achei o token anti-CSRF do Goodreads; recapture os cookies e tente de novo\"\n            )\n        })?;","sourceCodeStart":231,"sourceCodeEnd":267,"githubUrl":"https://github.com/tonhowtf/omniget/blob/8600b91f4246848bac346874daa9e61c1fc5677a/src-tauri/omniget-core/src/core/tools/lists/goodreads.rs#L231-L267","documentation":"trigger_and_wait fetches the Goodreads import page HTML and checks is_signed_out() before doing anything else. If the page indicates the user is not authenticated, the stored cookies captured by the browser extension are stale or absent, so the library aborts with this message asking the user to recapture cookies.","triggerScenarios":"Running the Goodreads export flow when the Fetcher's goodreads.com cookies are missing, expired, or belong to a logged-out session — detected by the sign-out markers in the IMPORT_URL page HTML.","commonSituations":"User logged out of Goodreads in the browser after capturing cookies; Goodreads session expired (weeks of inactivity); extension captured cookies before the user ever logged in; cookies captured on the wrong domain.","solutions":["Log into goodreads.com in the browser and recapture cookies with the extension, then rerun the operation.","Verify in the browser that goodreads.com/review/import shows the signed-in page (it should show your import/export history, not a login prompt).","If cookies are fresh but the check still fails, confirm the extension captured cookies for the goodreads.com domain specifically, not amazon.com (Goodreads accounts can be linked).","Clear old stored cookies for the domain in the extension first so stale values are not reused."],"exampleFix":"// before (stale cookies stored)\nrun(&fetcher, &opts).await?; // session invalid\n\n// after (extension recapture flow)\nextension.capture_cookies(\"https://www.goodreads.com\"); // user logged in\nrun(&fetcher, &opts).await?;","handlingStrategy":"validation","validationCode":"// before running, sanity-check stored cookies still yield a signed-in page\nlet page = fetcher.get_text(IMPORT_URL).await?;\nif is_signed_out(&page) {\n    prompt_cookie_recapture(); // pause flow before triggering export\n}","typeGuard":null,"tryCatchPattern":"match run(&fetcher, &opts).await {\n    Err(e) if e.to_string().contains(\"sessão do Goodreads\") => {\n        ui.ask_user_to_recapture_cookies(\"goodreads.com\");\n    }\n    r => r?,\n}","preventionTips":["Recapture cookies right before long-running Goodreads operations","Stay logged into goodreads.com in the browser the extension monitors","Purge stale cookies for the domain before recapturing"],"tags":["authentication","cookies","goodreads","session"],"backgroundTag":"authentication-required","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"}