fish2018/pansou · error

web search documents contained no valid links

Error message

web search documents contained no valid links

What it means

searchWeb fetches each candidate item's document concurrently (semaphore of 8) and builds final results. If every fetchPansoDocument call failed to yield a valid link, it raises 'web search documents contained no valid links'. Search results were found, but none could be converted into usable download links.

Solutions

  1. Log fetchPansoDocument errors per item to see whether failures are HTTP-level or parsing-level.
  2. Reduce concurrency (semaphore of 8) and add retry/backoff if detail pages are rate-limited.
  3. Update the detail-page link extraction logic if panso.vip changed its markup.
  4. Treat some failures as acceptable only when at least one result succeeds; otherwise surface per-item causes.

Example fix

// before
wg.Wait()
if len(results) == 0 {
    return nil, fmt.Errorf("web search documents contained no valid links")
}
// after
wg.Wait()
if len(results) == 0 {
    return nil, fmt.Errorf("web search documents contained no valid links (items=%d, lastErr=%v)", len(items), firstFetchErr)
}
Defensive patterns

Strategy: fallback

Try / catch

results, err := plugin.Search(keyword)
if err != nil && strings.Contains(err.Error(), "no valid links") {
    // all detail fetches failed: inspect per-item errors, throttle, or switch source
}

Prevention

When it happens

Trigger: After wg.Wait() in searchWeb, len(results) == 0 because every fetchPansoDocument call failed or produced a result without links — e.g. all detail pages non-200, or link extraction selectors broken.

Common situations: Detail-page endpoints moved or now require login; pan links expired/removed upstream; concurrency of 8 triggered rate limiting on all detail fetches; link parsing regex/selector outdated.

Understand the failure class

Background: EmptyResultError / "no results found": when an API or scraper succeeds but returns zero rows — this error's family across 9 libraries.

Related errors


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

Appendix: source

Thrown at plugin/sousou/sousou.go:238

		item := item
		wg.Add(1)
		go func() {
			defer wg.Done()
			sem <- struct{}{}
			defer func() { <-sem }()
			result, err := p.fetchPansoDocument(client, item)
			if err != nil {
				debugLog("document %s failed: %v", item.DocURL, err)
				return
			}
			mu.Lock()
			results = append(results, result)
			mu.Unlock()
		}()
	}
	wg.Wait()
	if len(results) == 0 {
		return nil, fmt.Errorf("web search documents contained no valid links")
	}
	return results, nil
}

func (p *SousouAsyncPlugin) fetchPansoDocument(client *http.Client, item pansoSearchItem) (model.SearchResult, error) {
	ctx, cancel := context.WithTimeout(context.Background(), 20*time.Second)
	defer cancel()
	req, err := http.NewRequestWithContext(ctx, http.MethodGet, item.DocURL, nil)
	if err != nil {
		return model.SearchResult{}, err
	}
	setSousouWebHeaders(req, SousouWebURL+"?q=")
	resp, err := client.Do(req)
	if err != nil {
		return model.SearchResult{}, err
	}
	defer resp.Body.Close()
	if resp.StatusCode != http.StatusOK {

View on GitHub (pinned to beaa561337)