fish2018/pansou · error

重新登录后未找到scraper实例

Error message

重新登录后未找到scraper实例

What it means

Internal invariant error: after a successful re-login triggered by a 403, the code looks up the fresh *cloudscraper.Scraper in p.scrapers by user.Hash and it is missing. reloginUser reported success (it should have Store()d the scraper), yet the map lookup failed.

Solutions

  1. Retry the request; this is often a transient race.
  2. Check for concurrent code paths that delete or overwrite p.scrapers entries for the user.
  3. Ensure user.Hash is stable and matches the key used in reloginUser's Store call.
  4. Report as a bug if reproducible: reloginUser succeeded but did not store under the expected hash.
Defensive patterns

Strategy: retry

Try / catch

results, err := p.Search(keyword)
if err != nil && strings.Contains(err.Error(), "未找到scraper实例") {
    time.Sleep(time.Second)
    results, err = p.Search(keyword) // transient race usually resolves on retry
}

Prevention

When it happens

Trigger: p.scrapers.Load(user.Hash) returns exists=false right after reloginUser succeeded — e.g. user.Hash was mutated concurrently, the map entry was deleted by another goroutine, or reloginUser stored under a different hash.

Common situations: Concurrent requests for the same user where one path clears/replaces scrapers; user record (Hash) changed between relogin and lookup; race conditions under high concurrency.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


AI-assisted analysis of fish2018/pansou@beaa561337 (2026-09-07). Data as JSON: /api/errors/68684b766c3fb96a. Report an issue: GitHub.

Appendix: source

Thrown at plugin/gying/gying.go:2405

	// 检测是否为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)
		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)
		}

View on GitHub (pinned to beaa561337)