fish2018/pansou · error
重新登录后scraper实例无效
Error message
重新登录后scraper实例无效
What it means
Internal invariant error: after re-login, the value stored in p.scrapers for user.Hash could not be asserted to a non-nil *cloudscraper.Scraper. The map should only ever contain Scraper instances stored by doLogin/reloginUser.
Solutions
- Audit all p.scrapers.Store calls to ensure only *cloudscraper.Scraper values are stored.
- Ensure doLogin never returns a nil scraper with a nil error.
- Retry the request; if persistent, report as a plugin bug.
- Re-login the user from scratch to repopulate a valid scraper.
Example fix
// before (doLogin failure path)
return nil, nil
// after
return nil, fmt.Errorf("login failed") // never return nil scraper with nil error Defensive patterns
Strategy: type-guard
Type guard
newScraper, ok := scraperVal.(*cloudscraper.Scraper)
if !ok || newScraper == nil {
return errors.New("invalid scraper stored; force re-login")
} Prevention
- Only store *cloudscraper.Scraper values into p.scrapers.
- Never return a nil scraper together with a nil error from doLogin.
- Run a nil/type check after every Store/Load pair in plugin code.
When it happens
Trigger: scraperVal.(*cloudscraper.Scraper) type assertion fails or the asserted pointer is nil — e.g. something stored a different type under the user's hash, or a nil scraper was stored.
Common situations: Code changes introduced another entry type into p.scrapers; a failed login path stored nil; mixing plugin versions sharing the same scraper map.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
AI-assisted analysis of fish2018/pansou@beaa561337 (2026-09-07).
Data as JSON: /api/errors/bc4db16717562eb4.
Report an issue: GitHub.
Appendix: source
Thrown at plugin/gying/gying.go:2410
}
// 尝试重新登录
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)
if err != nil {
return nil, fmt.Errorf("重新登录后搜索仍然失败: %w", err)
}
if syncErr := p.syncUserCookiesFromScraper(user, newScraper); syncErr != nil && DebugLog {
fmt.Printf("[Gying] ⚠️ 重登搜索后同步用户 %s Cookie失败: %v\n", user.Username, syncErr)
}
}
return results, err
}
View on GitHub (pinned to beaa561337)