{"record":{"id":"a7851bda2efc7691","repo":"jlcodes99/cockpit-tools","slug":"error-a7851b","errorCode":null,"errorMessage":"保存账号失败: {}","messagePattern":"保存账号失败: (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src-tauri/src/commands/oauth.rs","lineNumber":103,"sourceCode":"    ));\n\n    let token_data = models::TokenData::new(\n        token_res.access_token,\n        refresh_token,\n        token_res.expires_in,\n        Some(user_info.email.clone()),\n        None,\n        user_info.id.clone(),\n    )\n    .with_oauth_metadata(token_res.oauth_client_key, token_res.id_token);\n\n    let mut account = modules::upsert_account(\n        user_info.email.clone(),\n        user_info.get_display_name(),\n        token_data,\n    )\n    .map_err(|e| {\n        modules::logger::log_error(&format!(\"保存账号失败: {}\", e));\n        e\n    })?;\n\n    modules::account::apply_account_note_after_oauth(\n        &mut account,\n        modules::account::AccountNoteUpdate {\n            note,\n            two_factor_secret,\n            account_password,\n            phone_number,\n            mail_url,\n            aux_email,\n        },\n    )?;\n    let account = refresh_account_quota_after_login(account).await;\n\n    modules::logger::log_info(&format!(\"账号添加成功: {}\", account.email));\n","sourceCodeStart":85,"sourceCodeEnd":121,"githubUrl":"https://github.com/jlcodes99/cockpit-tools/blob/1ed8b77992d62ca81fabf744deb0839ad361d5bf/src-tauri/src/commands/oauth.rs#L85-L121","documentation":"Once user info and tokens are collected, start_oauth_login persists the account via modules::upsert_account(email, display_name, token_data). This error is logged and returned when the upsert fails, meaning the OAuth authorization succeeded but the account could not be saved to local storage.","triggerScenarios":"upsert_account returns Err: local storage/DB write failure (locked database, disk full, permission-denied store file), serialization failure of token_data, or a uniqueness/constraint violation on the email key.","commonSituations":"Disk full or read-only app data directory; corrupted or locked local account store (another instance running); schema change after an app update making stored token_data incompatible; antivirus locking the data file.","solutions":["Check disk space and write permissions on the app's data directory, then retry the login","Close other running instances of the app that may hold a lock on the account store","Back up and remove/repair a corrupted account store file, then re-run OAuth","Update the app if the failure started after a version change (token_data schema migration issue)"],"exampleFix":"// before\nlet mut account = modules::upsert_account(user_info.email.clone(), user_info.get_display_name(), token_data)\n    .map_err(|e| {\n        modules::logger::log_error(&format!(\"保存账号失败: {}\", e));\n        e\n    })?;\n// after\nlet mut account = modules::upsert_account(user_info.email.clone(), user_info.get_display_name(), token_data)\n    .map_err(|e| {\n        modules::logger::log_error(&format!(\"保存账号失败: {}\", e));\n        format!(\"保存账号失败（请检查磁盘空间与数据目录权限）: {}\", e)\n    })?;","handlingStrategy":"validation","validationCode":"// check storage health before running the whole OAuth flow\nif !is_dir_writable(&app_data_dir()) {\n    return Err(\"应用数据目录不可写，请检查权限\".to_string());\n}\nif free_disk_bytes(&app_data_dir())? < MIN_REQUIRED_BYTES {\n    return Err(\"磁盘空间不足，无法保存账号\".to_string());\n}\nif account_store_locked() {\n    return Err(\"账号存储被其他实例占用，请关闭其他窗口后重试\".to_string());\n}","typeGuard":null,"tryCatchPattern":"let mut account = match modules::upsert_account(user_info.email.clone(), user_info.get_display_name(), token_data) {\n    Ok(a) => a,\n    Err(e) => {\n        log_error(&format!(\"保存账号失败: {}\", e));\n        return Err(format!(\"保存账号失败（请检查磁盘空间与数据目录权限）: {}\", e));\n    }\n};","preventionTips":["Keep free disk space and writable app-data permissions","Don't run multiple app instances that share the same account store","After app updates, verify token_data schema migrations ran cleanly","Back up the account store before manual edits or cleanup"],"tags":["oauth","account-storage","persistence","disk"],"backgroundTag":"account-persist-failed","analyzedSha":"1ed8b77992d62ca81fabf744deb0839ad361d5bf","analyzedAt":"2026-09-05T09:51:41.178Z","contentChangedAt":"2026-09-05T09:51:41.178Z","schemaVersion":2},"datasetVersion":"2026-09-12T12:17:11.808Z"}