feat: 认证失败时停止重连并提示用户
密码错误、账户禁用、令牌过期或限流等永久性认证错误不再无限 重连,改为置 StateError 并通过 EvError 弹窗告知用户具体原因 (中英文本地化)。网络错误仍正常指数退避重试。 - protocol: 新增 AuthErrorCode 类型与消息映射 - transport: AuthError/ServerError 携带 Code 字段 - vpn: run() 循环识别致命认证错误并停止,新增 onError 回调 - ipc/daemon/ui: 打通错误码到 UI 的本地化展示
This commit is contained in:
+23
-2
@@ -241,14 +241,35 @@ func (a *App) eventLoop() {
|
||||
}
|
||||
case ipc.EvError:
|
||||
fyne.Do(func() {
|
||||
if ev.Message != "" {
|
||||
showError(i18n.T("DlgVPNError"), ev.Message, a.window)
|
||||
msg := authErrorMessage(ev.Code, ev.Message)
|
||||
if msg != "" {
|
||||
showError(i18n.T("DlgAuthError"), msg, a.window)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// authErrorMessage maps a stable auth-error code (carried by the EvError
|
||||
// IPC event from the daemon) to a localized user-facing string. For an
|
||||
// unknown or empty code it falls back to the raw server message.
|
||||
func authErrorMessage(code, fallback string) string {
|
||||
switch code {
|
||||
case "wrong_credentials":
|
||||
return i18n.T("AuthErrWrongCredentials")
|
||||
case "user_disabled":
|
||||
return i18n.T("AuthErrUserDisabled")
|
||||
case "token_invalid":
|
||||
return i18n.T("AuthErrTokenInvalid")
|
||||
case "rate_limited":
|
||||
return i18n.T("AuthErrRateLimited")
|
||||
case "malformed":
|
||||
return i18n.T("AuthErrMalformed")
|
||||
default:
|
||||
return fallback
|
||||
}
|
||||
}
|
||||
|
||||
// applyState updates UI elements for a state change.
|
||||
func (a *App) applyState(state string) {
|
||||
switch stats.State(state) {
|
||||
|
||||
Reference in New Issue
Block a user