fish2018/pansou · error

[ ] 获取分享链接失败

Error message

[%s] 获取分享链接失败: %w

What it means

searchImpl resolves share links for each search hit concurrently; if every resolution attempt failed (resolvedCount == 0) and at least one error was captured, it wraps the first error (firstErr) with 获取分享链接失败. This means none of the results could get a usable share link, so no results are returned.

Solutions

  1. Inspect the wrapped firstErr (%w) for the root cause — network error vs HTTP status vs parse failure.
  2. Test connectivity to the Yingso upstream from the host (curl the endpoint).
  3. If authentication/cookies are involved, refresh them.
  4. Add retry with backoff for transient network failures.
Defensive patterns

Strategy: fallback

Try / catch

results, err := search(keyword)
if err != nil {
    if strings.Contains(err.Error(), "获取分享链接失败") {
        log.Printf("all share-link resolutions failed: %v", err)
        return cachedOrEmptyResults
    }
    return err
}

Prevention

When it happens

Trigger: All concurrent requests to resolve share links for the found items failed — network errors, upstream timeouts, anti-bot blocks, or invalid item metadata (e.g. missing share IDs) — so resolvedCount stayed 0.

Common situations: Yingso upstream is down or blocking the client IP; expired session/cookies cause every link-resolution call to fail; network outage or proxy misconfiguration on the host running the plugin.

Related errors


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

Appendix: source

Thrown at plugin/yingso/yingso.go:170

	wg.Wait()
	close(resultCh)

	var firstErr error
	resolvedCount := 0
	for item := range resultCh {
		if item.err != nil {
			if firstErr == nil {
				firstErr = item.err
			}
			continue
		}
		resolved[item.index] = item.result
		valid[item.index] = true
		resolvedCount++
	}
	if resolvedCount == 0 && firstErr != nil {
		return nil, fmt.Errorf("[%s] 获取分享链接失败: %w", p.Name(), firstErr)
	}

	results := make([]model.SearchResult, 0, resolvedCount)
	seen := make(map[string]struct{}, resolvedCount)
	for index, result := range resolved {
		if !valid[index] || len(result.Links) == 0 {
			continue
		}
		linkKey := result.Links[0].URL + "\x00" + result.Links[0].Password
		if _, exists := seen[linkKey]; exists {
			continue
		}
		seen[linkKey] = struct{}{}
		results = append(results, result)
	}

	return plugin.FilterResultsByKeyword(results, keyword), nil
}

View on GitHub (pinned to beaa561337)