fish2018/pansou · error
解密密码失败
Error message
解密密码失败: %w
What it means
Wraps the failure of p.decryptPassword when trying to decrypt a user's stored EncryptedPassword during the login flow. The library keeps user passwords encrypted at rest and decrypts them just before calling doLogin; if decryption fails (wrong key, corrupted ciphertext, unsupported format), the login aborts and this wrapped error is returned so the underlying cause is preserved via %w.
Solutions
- Re-enter/re-save the account's plain password so EncryptedPassword is re-encrypted with the current key.
- Verify the encryption key/configuration is the same one used when the password was stored.
- Enable DebugLog to see the raw decrypt error printed by decryptPassword and fix the specific cause.
- Update the plugin if the EncryptedPassword was produced by an older/other version with a different scheme.
Example fix
// before user.EncryptedPassword = oldBase64BlobFromOtherInstance // after user.EncryptedPassword = encryptWithCurrentKey(plainPassword) // re-save credentials
Defensive patterns
Strategy: try-catch
Validate before calling
if user == nil || user.EncryptedPassword == "" {
return errors.New("user has no encrypted password stored")
} Try / catch
password, err := p.decryptPassword(user.EncryptedPassword)
if err != nil {
// errors.Is/As on the wrapped cause; recover by re-saving credentials
return fmt.Errorf("re-save credentials for user %s: %w", user.Username, err)
} Prevention
- Always save credentials through the plugin's own encrypt path, never paste encrypted blobs manually.
- Keep the encryption key/config stable across deployments or provide a migration step.
- Back up the key used to encrypt stored passwords.
When it happens
Trigger: Calling the plugin's login/relogin path (e.g. reloginUser) for a user whose EncryptedPassword cannot be decrypted: ciphertext produced by a different encryption key or plugin version, empty/corrupted stored password, or an unsupported encryption scheme in decryptPassword.
Common situations: Users migrated from another instance with a different encryption key; encrypted password blob truncated in the config/store; plugin upgraded and the decryption scheme changed; EncryptedPassword field pasted manually instead of the encrypted value.
Related errors
- login required
- loginResp.Message (dynamic remote login failure message)
- username cannot be empty
- token cannot be empty
- invalid token
AI-assisted analysis of fish2018/pansou@beaa561337 (2026-09-07).
Data as JSON: /api/errors/b35654c05d1ca797.
Report an issue: GitHub.
Appendix: source
Thrown at plugin/gying/gying.go:2276
}
return b
}
// ============ 重新登录逻辑 ============
// reloginUser 重新登录指定用户
func (p *GyingPlugin) reloginUser(user *User) error {
if DebugLog {
fmt.Printf("[Gying] 🔄 开始重新登录用户: %s\n", user.Username)
}
// 解密密码
password, err := p.decryptPassword(user.EncryptedPassword)
if err != nil {
if DebugLog {
fmt.Printf("[Gying] ❌ 解密密码失败: %v\n", err)
}
return fmt.Errorf("解密密码失败: %w", err)
}
// 执行登录
scraper, cookie, err := p.doLogin(user.Username, password)
if err != nil {
if DebugLog {
fmt.Printf("[Gying] ❌ 重新登录失败: %v\n", err)
}
return fmt.Errorf("重新登录失败: %w", err)
}
// 更新scraper实例
p.scrapers.Store(user.Hash, scraper)
// 更新用户信息
user.Cookie = cookie
user.LoginAt = time.Now()
user.ExpireAt = time.Now().AddDate(0, 4, 0)View on GitHub (pinned to beaa561337)