{"record":{"id":"98dce1cc8edf11bd","repo":"tonhowtf/omniget","slug":"failed-to-parse-content-mod","errorCode":null,"errorMessage":"Failed to parse content: {}","messagePattern":"Failed to parse content: (.+?)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"src-tauri/src/platforms/bilibili/mod.rs","lineNumber":125,"sourceCode":"    if url.is_empty() {\n        return Err(anyhow!(\"No URL available\"));\n    }\n\n    let slug = active_account_slug();\n    let client = build_api_client(slug.as_deref(), opts.user_agent.as_deref())?;\n\n    let mut effective_url = url.to_string();\n    if url_kind::is_b23_short(&effective_url) {\n        if let Ok(resolved) = url_kind::resolve_b23(&client, &effective_url).await {\n            effective_url = resolved;\n        }\n    }\n\n    let kind = url_kind::detect(&effective_url)\n        .map_err(|e| anyhow!(\"Failed to detect URL kind: {}\", e.i18n_key()))?;\n    let parsed = parser::parse(&client, &kind)\n        .await\n        .map_err(|e| anyhow!(\"Failed to parse content: {}\", e.i18n_key()))?;\n\n    let settings = crate::storage::config::load_settings_standalone();\n    let container = mux::container_from_setting(&settings.download.bilibili_container);\n    let danmaku_format = danmaku_format_from_setting(&settings.download.bilibili_danmaku_format);\n    let cover_format = cover::CoverFormat::from_str(&settings.download.bilibili_cover_format);\n    let template_set = naming::TemplateSet {\n        video: settings.download.bilibili_naming_video.clone(),\n        multi_part: settings.download.bilibili_naming_multi_part.clone(),\n        bangumi: settings.download.bilibili_naming_bangumi.clone(),\n        cheese: settings.download.bilibili_naming_cheese.clone(),\n        collection: settings.download.bilibili_naming_collection.clone(),\n    };\n    let first_item_owned = parsed.items.first().cloned().unwrap_or_default();\n    let naming_kind = naming::classify(&kind, &first_item_owned);\n    let naming_inputs = naming::NamingInputs {\n        item: &first_item_owned,\n        metadata: &parsed.metadata,\n        parsed_title: &parsed.title,","sourceCodeStart":107,"sourceCodeEnd":143,"githubUrl":"https://github.com/tonhowtf/omniget/blob/8600b91f4246848bac346874daa9e61c1fc5677a/src-tauri/src/platforms/bilibili/mod.rs#L107-L143","documentation":"After URL detection succeeds, `api_engine_download` calls `parser::parse(&client, &kind)` to fetch and interpret content metadata via the Bilibili API; any parser error's i18n key is wrapped in `anyhow!(\"Failed to parse content: {}\")`. This is the top-level wrapper for all upstream API/parse failures.","triggerScenarios":"Calling `download` where the Bilibili API request inside `parser::parse` fails — HTTP errors, rate limiting, login-required/charge-only content, deleted or private videos, API response shape changes breaking the parser, or invalid account credentials/cookies.","commonSituations":"Expired Bilibili cookies causing auth-required responses; region-restricted content returning unavailable; Bilibili changing its API JSON structure after an app update gap; network failures or 412/429 anti-bot responses from Bilibili.","solutions":["Read the wrapped i18n key to identify the underlying cause (auth, not-found, rate-limit) and address it specifically.","Refresh login credentials/cookies for the active account.","Retry after a delay if rate-limited; use a realistic User-Agent via `opts.user_agent`.","Update the app/parsers if Bilibili's API format changed.","Confirm the content still exists and is publicly playable in a browser."],"exampleFix":"// before\nlet parsed = parser::parse(&client, &kind).await.map_err(|e| anyhow!(\"Failed to parse content: {}\", e.i18n_key()))?;\n// after\nlet parsed = match parser::parse(&client, &kind).await {\n    Ok(p) => p,\n    Err(e) if is_auth_error(&e) => { refresh_cookies(&client).await?; parser::parse(&client, &kind).await? }\n    Err(e) => return Err(anyhow!(\"Failed to parse content: {}\", e.i18n_key())),\n};","handlingStrategy":"try-catch","validationCode":"// pre-flight: ensure account/cookies are configured before parsing\nif active_account_slug().is_none() && content_requires_login(&kind) {\n    return Err(anyhow!(\"login required\"));\n}","typeGuard":null,"tryCatchPattern":"match download(info, opts, progress).await {\n    Err(e) if e.to_string().contains(\"Failed to parse content\") => {\n        log_parse_error(&e); // inspect i18n key: auth vs not-found vs rate-limit\n        maybe_refresh_credentials_and_retry().await?;\n    }\n    Err(e) => return Err(e),\n    Ok(_) => {},\n}","preventionTips":["Keep Bilibili cookies/credentials fresh for the active account.","Back off and retry on rate-limit/anti-bot responses; set a realistic User-Agent.","Update the app when Bilibili API formats change.","Inspect the i18n key inside the error to route auth, not-found, and network failures to different handlers."],"tags":["api","parsing","network","bilibili"],"backgroundTag":"api-error-response","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"}