jlcodes99/cockpit-tools · error
获取用户信息失败: {}
Error message
获取用户信息失败: {} What it means
After obtaining OAuth tokens, start_oauth_login calls modules::oauth::get_user_info(&token_res.access_token) to fetch the Google account profile (email, display name). This error is logged and returned when that userinfo API call fails, aborting account creation since the account is keyed by email.
Source
Thrown at src-tauri/src/commands/oauth.rs:77
modules::logger::log_info("OAuth 授权成功,检查 refresh_token...");
let refresh_token = token_res.refresh_token.ok_or_else(|| {
let msg = "未获取到 Refresh Token。\n\n\
可能原因:您之前已授权过此应用\n\n\
解决方案:\n\
1. 访问 https://myaccount.google.com/permissions\n\
2. 撤销 'Antigravity Tools' 的访问权限\n\
3. 重新进行 OAuth 授权"
.to_string();
modules::logger::log_error(&msg);
msg
})?;
modules::logger::log_info("获取用户信息...");
let user_info = modules::oauth::get_user_info(&token_res.access_token)
.await
.map_err(|e| {
modules::logger::log_error(&format!("获取用户信息失败: {}", e));
e
})?;
modules::logger::log_info(&format!(
"用户: {} ({})",
user_info.email,
user_info.name.as_deref().unwrap_or("无名称")
));
let token_data = models::TokenData::new(
token_res.access_token,
refresh_token,
token_res.expires_in,
Some(user_info.email.clone()),
None,
user_info.id.clone(),
)
.with_oauth_metadata(token_res.oauth_client_key, token_res.id_token);View on GitHub (pinned to 1ed8b77992)
Solutions
- Check that the OAuth request includes the userinfo.email and userinfo.profile scopes, then re-run authorization
- Verify network connectivity / proxy settings and retry the login
- Check the wrapped error detail: 401 means re-authenticate; 403 means missing scope; 5xx/timeout means retry later
- Confirm the access token is used promptly after exchange and not cached stale
Example fix
// before
let user_info = modules::oauth::get_user_info(&token_res.access_token)
.await
.map_err(|e| {
modules::logger::log_error(&format!("获取用户信息失败: {}", e));
e
})?;
// after
let user_info = modules::oauth::get_user_info(&token_res.access_token)
.await
.map_err(|e| {
modules::logger::log_error(&format!("获取用户信息失败: {}", e));
if e.contains("401") || e.contains("403") {
format!("访问令牌无效或权限不足,请重新授权: {}", e)
} else {
format!("获取用户信息失败,请检查网络后重试: {}", e)
}
})?; Defensive patterns
Strategy: retry
Validate before calling
// ensure the token exchange requested the scopes needed for userinfo
if !granted_scopes.contains("userinfo.email") || !granted_scopes.contains("userinfo.profile") {
return Err("授权缺少 userinfo 权限,请重新授权并勾选完整权限".to_string());
} Try / catch
let user_info = match modules::oauth::get_user_info(&token_res.access_token).await {
Ok(u) => u,
Err(e) if is_auth_error(&e) => return Err(format!("访问令牌无效或权限不足,请重新授权: {}", e)),
Err(e) if is_transient(&e) => match modules::oauth::get_user_info(&token_res.access_token).await {
Ok(u) => u,
Err(e2) => return Err(format!("获取用户信息失败,请检查网络后重试: {}", e2)),
},
Err(e) => return Err(format!("获取用户信息失败: {}", e)),
}; Prevention
- Include userinfo.email and userinfo.profile scopes in the OAuth request
- Use the access token promptly after exchange before it expires
- Check proxy/DNS if userinfo calls consistently fail
- Distinguish 401 (re-auth) from 403 (scope) from 5xx (retry) in error handling
When it happens
Trigger: get_user_info(access_token) returns Err: the userinfo endpoint returned 401/403 (invalid or insufficient-scope access token), a network/timeout error, or an unparseable response.
Common situations: OAuth scope not including userinfo.profile/userinfo.email so Google rejects the userinfo call; access token already expired or revoked by the time the call runs; offline/proxy/network interruption; Google userinfo endpoint outage.
Related errors
- OAuth 流程失败: {}
- 未获取到 Refresh Token。 可能原因:您之前已授权过此应用 解决方案: 1. 访问 https://my
- Claude login start 响应缺少关键字段
- Claude OAuth start 响应缺少关键字段
- Qoder OAuth start 响应缺少关键字段
AI-assisted analysis of jlcodes99/cockpit-tools@1ed8b77992 (2026-09-05).
Data as JSON: /api/errors/ac0dc6ff891202b6.
Report an issue: GitHub.