{"record":{"id":"0ad8b6458526f726","repo":"lbjlaq/Antigravity-Manager","slug":"api-token","errorCode":null,"errorMessage":"[API] 清除 Token 统计数据失败: {}","messagePattern":"\\[API\\] 清除 Token 统计数据失败: (.+?)","errorType":"http","errorClass":null,"httpStatus":500,"severity":"error","filePath":"src-tauri/src/proxy/server.rs","lineNumber":2637,"sourceCode":"}\n\nasync fn admin_clear_token_stats() -> impl IntoResponse {\n    let res = tokio::task::spawn_blocking(|| {\n        // Clear databases (brute force)\n        if let Ok(path) = token_stats::get_db_path() {\n            let _ = std::fs::remove_file(path);\n        }\n        let _ = token_stats::init_db();\n    })\n    .await;\n\n    match res {\n        Ok(_) => {\n            logger::log_info(\"[API] 已清除所有 Token 统计数据\");\n            StatusCode::OK\n        }\n        Err(e) => {\n            logger::log_error(&format!(\"[API] 清除 Token 统计数据失败: {}\", e));\n            StatusCode::INTERNAL_SERVER_ERROR\n        }\n    }\n}\n\nasync fn admin_get_update_settings() -> impl IntoResponse {\n    // 從真實模組加載設置\n    match crate::modules::update_checker::load_update_settings() {\n        Ok(s) => Json(serde_json::to_value(s).unwrap_or_default()),\n        Err(_) => Json(serde_json::json!({\n            \"auto_check\": true,\n            \"last_check_time\": 0,\n            \"check_interval_hours\": 24\n        })),\n    }\n}\n\nasync fn admin_check_for_updates() -> Result<impl IntoResponse, (StatusCode, Json<ErrorResponse>)> {","sourceCodeStart":2619,"sourceCodeEnd":2655,"githubUrl":"https://github.com/lbjlaq/Antigravity-Manager/blob/90a2b6b20797e2e593a83d0c54ab86037863fe70/src-tauri/src/proxy/server.rs#L2619-L2655","documentation":"The admin_clear_token_stats endpoint in src-tauri/src/proxy/server.rs spawns a blocking task that deletes the token-stats SQLite database file (token_stats::get_db_path() then std::fs::remove_file) and reinitializes it via token_stats::init_db(). The handler only returns 500 with the log '[API] 清除 Token 统计数据失败: {e}' when the spawn_blocking JoinHandle itself yields Err — i.e. the blocking task panicked (e.g. init_db panicked on a locked/unwritable database) or the task was cancelled at runtime, not when remove_file fails (that error is intentionally swallowed).","triggerScenarios":"tokio::task::spawn_blocking(...).await returns Err(e) (a JoinError): the closure panicked inside token_stats::init_db (SQLite open failure with panic, migration error) or the runtime is shutting down and the task was cancelled. Log message is Chinese: '[API] 清除 Token 统计数据失败'.","commonSituations":"Token-stats database file locked by another connection/OS file lock so init_db panics; database path not writable (permissions or read-only volume); runtime shutdown/cancel racing the admin request during app exit; corrupted DB causing an unwrap/panic inside init_db.","solutions":["Check the server log for the JoinError detail after '清除 Token 统计数据失败' — a panic message points at init_db; a 'task was cancelled' means the runtime was shutting down (retry while the app is fully running).","Verify the token-stats DB path (token_stats::get_db_path) is writable and not held open/locked by another process; close other app instances and delete the DB file manually, then restart the app.","If the DB is corrupted, remove the file manually while the app is stopped and let init_db recreate it on next start.","Check file permissions on the DB's directory; fix ownership so the app user can create/delete the database file.","Retry the clear operation; a transient panic during shutdown will not reproduce under normal operation."],"exampleFix":"// before: init_db panics on locked/corrupt DB -> 500 清除 Token 统计数据失败\n// terminal (app stopped):\nrm \"$(path from token_stats::get_db_path)\"   // e.g. ~/Library/Application Support/<app>/token_stats.db\n// after: restart app, retry POST admin clear -> 200 已清除所有 Token 统计数据","handlingStrategy":"retry","validationCode":"// Pre-check that the token-stats DB path exists and is writable before clearing\nimport { accessSync, constants } from 'fs';\nconst dbPath = await invoke('get_token_stats_db_path');\ntry { accessSync(dbPath, constants.W_OK); } catch { console.warn('DB path not writable; clear may fail'); }","typeGuard":null,"tryCatchPattern":"const res = await fetch('/api/admin/clear-token-stats', { method: 'POST' });\nif (res.status === 500) {\n  // JoinError: blocking task panicked or was cancelled (e.g. app shutting down)\n  console.warn('clear failed; close other app instances, ensure DB not locked, and retry');\n  await retryWithBackoff(() => fetch('/api/admin/clear-token-stats', { method: 'POST' }), 2);\n}","preventionTips":["Clear stats only while the app is fully running and idle — shutdown cancels the blocking task.","Ensure no second app instance holds the token-stats SQLite file open.","Keep the DB directory writable and free of lock files; stop the app before manually deleting the DB.","If the DB is corrupted, delete the file while the app is stopped and let init_db recreate it.","Retry once on 500 — transient panics/cancellations won't reproduce under normal conditions."],"tags":["http","api","database","sqlite","token-stats"],"backgroundTag":"database-query-failed","analyzedSha":"90a2b6b20797e2e593a83d0c54ab86037863fe70","analyzedAt":"2026-09-19T08:34:01.322Z","contentChangedAt":"2026-09-19T08:34:01.322Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}