lbjlaq/Antigravity-Manager · error
[API] 清除 Token 统计数据失败
Error message
[API] 清除 Token 统计数据失败: {} What it means
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).
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.
Example fix
// before: init_db panics on locked/corrupt DB -> 500 清除 Token 统计数据失败 // terminal (app stopped): rm "$(path from token_stats::get_db_path)" // e.g. ~/Library/Application Support/<app>/token_stats.db // after: restart app, retry POST admin clear -> 200 已清除所有 Token 统计数据
Defensive patterns
Strategy: retry
Validate before calling
// Pre-check that the token-stats DB path exists and is writable before clearing
import { accessSync, constants } from 'fs';
const dbPath = await invoke('get_token_stats_db_path');
try { accessSync(dbPath, constants.W_OK); } catch { console.warn('DB path not writable; clear may fail'); } Try / catch
const res = await fetch('/api/admin/clear-token-stats', { method: 'POST' });
if (res.status === 500) {
// JoinError: blocking task panicked or was cancelled (e.g. app shutting down)
console.warn('clear failed; close other app instances, ensure DB not locked, and retry');
await retryWithBackoff(() => fetch('/api/admin/clear-token-stats', { method: 'POST' }), 2);
} Prevention
- 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.
When it happens
Trigger: 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 统计数据失败'.
Common situations: 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.
Understand the failure class
Background: Database query failed: Internal Server Error 500s wrapping SQL, Prisma, and connection failures — what to check first — this error's family across 16 libraries.
Related errors
AI-assisted analysis of lbjlaq/Antigravity-Manager@90a2b6b207 (2026-09-19).
Data as JSON: /api/errors/0ad8b6458526f726.
Report an issue: GitHub.
Appendix: source
Thrown at src-tauri/src/proxy/server.rs:2637
}
async fn admin_clear_token_stats() -> impl IntoResponse {
let res = tokio::task::spawn_blocking(|| {
// Clear databases (brute force)
if let Ok(path) = token_stats::get_db_path() {
let _ = std::fs::remove_file(path);
}
let _ = token_stats::init_db();
})
.await;
match res {
Ok(_) => {
logger::log_info("[API] 已清除所有 Token 统计数据");
StatusCode::OK
}
Err(e) => {
logger::log_error(&format!("[API] 清除 Token 统计数据失败: {}", e));
StatusCode::INTERNAL_SERVER_ERROR
}
}
}
async fn admin_get_update_settings() -> impl IntoResponse {
// 從真實模組加載設置
match crate::modules::update_checker::load_update_settings() {
Ok(s) => Json(serde_json::to_value(s).unwrap_or_default()),
Err(_) => Json(serde_json::json!({
"auto_check": true,
"last_check_time": 0,
"check_interval_hours": 24
})),
}
}
async fn admin_check_for_updates() -> Result<impl IntoResponse, (StatusCode, Json<ErrorResponse>)> {View on GitHub (pinned to 90a2b6b207)