{"record":{"id":"282fd760de8714cf","repo":"tonhowtf/omniget","slug":"e-to-string-cookie","errorCode":null,"errorMessage":"e.to_string()","messagePattern":"e\\.to_string\\(\\)","errorType":"exception","errorClass":"std::io::Error","httpStatus":null,"severity":"error","filePath":"src-tauri/omniget-core/src/platforms/bilibili/cookie.rs","lineNumber":70,"sourceCode":"        Some(p) => p,\n        None => return AnonymousCookieState::default(),\n    };\n    let content = match std::fs::read_to_string(&path) {\n        Ok(c) => c,\n        Err(_) => return AnonymousCookieState::default(),\n    };\n    serde_json::from_str(&content).unwrap_or_default()\n}\n\npub fn save_state(state: &AnonymousCookieState) -> std::io::Result<()> {\n    let path = meta_file_path().ok_or_else(|| {\n        std::io::Error::new(std::io::ErrorKind::Other, \"app_data_dir unavailable\")\n    })?;\n    if let Some(parent) = path.parent() {\n        std::fs::create_dir_all(parent)?;\n    }\n    let serialized = serde_json::to_string_pretty(state)\n        .map_err(|e| std::io::Error::new(std::io::ErrorKind::InvalidData, e.to_string()))?;\n    std::fs::write(path, serialized)\n}\n\npub async fn ensure_fresh() -> Result<AnonymousCookieState> {\n    let cached = load_state();\n    if cached.is_fresh() {\n        write_netscape_for_anonymous(&cached).ok();\n        return Ok(cached);\n    }\n    bootstrap_anonymous().await\n}\n\npub async fn bootstrap_anonymous() -> Result<AnonymousCookieState> {\n    let ua = super::api::DEFAULT_USER_AGENT;\n    let now_ms = now_ms();\n    let uuid = gen_uuid_b_lsid();\n    let b_lsid = gen_b_lsid();\n    let b_nut = now_ms.to_string();","sourceCodeStart":52,"sourceCodeEnd":88,"githubUrl":"https://github.com/tonhowtf/omniget/blob/8600b91f4246848bac346874daa9e61c1fc5677a/src-tauri/omniget-core/src/platforms/bilibili/cookie.rs#L52-L88","documentation":"In save_state, after resolving the path, the state is serialized with serde_json::to_string_pretty. Serialization failures (the AnonymousCookieState contains a value serde cannot serialize, e.g. a map with non-string keys or a NaN float) are converted into an io::Error of Kind::InvalidData whose message is just e.to_string(). This aborts writing the anonymous cookie state.","triggerScenarios":"Calling save_state (via bootstrap_anonymous) with an AnonymousCookieState whose fields fail serde_json serialization: unexpected non-string map keys, unserializable numeric values (NaN/Infinity floats from timestamps/tokens), or a struct field type change without updating serialization.","commonSituations":"A struct refactor added a field type serde_json can't handle; corrupted in-memory state built from bad server responses (NaN expiry); version drift where old cached structs no longer match the serde derive.","solutions":["Inspect the inner serde error (the io error's message) to find which field failed to serialize.","Validate state values before saving — replace NaN/Infinity numbers with defaults (0 or None as Option).","Change offending fields to serializable types (Option<f64>, String keys in maps).","Use #[serde(default)] on new fields so old-state compatibility is maintained."],"exampleFix":"// before\nexpires_at: f64, // can hold NaN\n// after\n#[serde(default)]\nexpires_at: Option<f64>, // None instead of NaN; always serializes","handlingStrategy":"validation","validationCode":"fn state_serializable(state: &AnonymousCookieState) -> bool {\n    serde_json::to_string(state).is_ok()\n}\n// call before save_state\nif !state_serializable(&state) { log::warn!(\"cookie state not serializable; skipping save\"); }","typeGuard":null,"tryCatchPattern":"match save_state(&state) {\n    Err(e) if e.kind() == std::io::ErrorKind::InvalidData => {\n        log::warn!(\"cookie state serialization failed: {e}\");\n    }\n    r => r?,\n}","preventionTips":["Keep numeric fields Option-wrapped so NaN/Infinity never enters the state","Add #[serde(default)] to new fields for backward compatibility","Test round-trip serialization of AnonymousCookieState in CI","Sanitize server-derived values before building the state struct"],"tags":["bilibili","cookie","serialization","serde"],"backgroundTag":"json-marshal-failed","analyzedSha":"8600b91f4246848bac346874daa9e61c1fc5677a","analyzedAt":"2026-09-12T14:29:19.317Z","contentChangedAt":"2026-09-12T14:29:19.317Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}