fish2018/pansou · error
403错误且重新登录失败
Error message
403错误且重新登录失败: %w
What it means
Returned when a search request hit HTTP 403 (session expired or Cloudflare challenge) and the automatic re-login via reloginUser also failed. The original relogin error is wrapped so the caller sees both that a 403 occurred and why recovery failed.
Solutions
- Fix the underlying relogin error (see the wrapped %w cause): re-save valid credentials.
- Check site availability and anti-bot status; retry after it recovers.
- Manually refresh the user's cookies/session.
- Enable DebugLog to see which step of relogin failed.
Defensive patterns
Strategy: retry
Validate before calling
// pre-check stored credentials exist before relying on automatic relogin
if user == nil || user.EncryptedPassword == "" {
return errors.New("cannot auto-relogin: no stored credentials")
} Try / catch
results, err := p.Search(keyword)
var ctxErr *fmt.wrapError
if err != nil && strings.Contains(err.Error(), "403") {
// 403 + failed relogin: back off and verify credentials before retrying
time.Sleep(retryDelay)
results, err = p.Search(keyword)
} Prevention
- Keep valid credentials stored so automatic re-login can succeed.
- Persist cookies to reduce 403-triggered re-login frequency.
- Monitor site availability before assuming a credential problem.
When it happens
Trigger: searchWithScraper receives a 403 response; the code checks for 403 and calls p.reloginUser(user); reloginUser returns a non-nil error (decrypt or doLogin failure), producing this wrapped error.
Common situations: Session cookie expired long ago and stored credentials are also stale/invalid; site is down or challenging so both the original request and the re-login fail; encryption key mismatch causing the decrypt step inside relogin to fail.
Understand the failure class
Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.
Related errors
AI-assisted analysis of fish2018/pansou@beaa561337 (2026-09-07).
Data as JSON: /api/errors/0942d8e87e38c839.
Report an issue: GitHub.
Appendix: source
Thrown at plugin/gying/gying.go:2399
results, err := p.searchWithScraper(keyword, scraper)
if err == nil {
if syncErr := p.syncUserCookiesFromScraper(user, scraper); syncErr != nil && DebugLog {
fmt.Printf("[Gying] ⚠️ 搜索后同步用户 %s Cookie失败: %v\n", user.Username, syncErr)
}
}
// 检测是否为403错误
if err != nil && strings.Contains(err.Error(), "403") {
if DebugLog {
fmt.Printf("[Gying] ⚠️ 检测到403错误,尝试重新登录用户 %s\n", user.Username)
}
// 尝试重新登录
if reloginErr := p.reloginUser(user); reloginErr != nil {
if DebugLog {
fmt.Printf("[Gying] ❌ 重新登录失败: %v\n", reloginErr)
}
return nil, fmt.Errorf("403错误且重新登录失败: %w", reloginErr)
}
// 获取新的scraper实例
scraperVal, exists := p.scrapers.Load(user.Hash)
if !exists {
return nil, fmt.Errorf("重新登录后未找到scraper实例")
}
newScraper, ok := scraperVal.(*cloudscraper.Scraper)
if !ok || newScraper == nil {
return nil, fmt.Errorf("重新登录后scraper实例无效")
}
// 使用新scraper重试搜索
if DebugLog {
fmt.Printf("[Gying] 🔄 使用新登录状态重试搜索\n")
}
results, err = p.searchWithScraper(keyword, newScraper)View on GitHub (pinned to beaa561337)