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

  1. 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).
  2. 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.
  3. If the DB is corrupted, remove the file manually while the app is stopped and let init_db recreate it on next start.
  4. Check file permissions on the DB's directory; fix ownership so the app user can create/delete the database file.
  5. 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

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)