fish2018/pansou · error

[ ] suggest 响应异常: host= code= msg=

Error message

[%s] suggest 响应异常: host=%s code=%d msg=%s

What it means

Raised in searchSuggest (plugin/qiwei/qiwei.go:214) when the suggest JSON parses but indicates an abnormal result: resp.Code != 1 AND resp.List is empty. The body is valid JSON from the site's API, but it reports a business-level failure (its own error code and msg) rather than a normal result. This treats a legitimately empty search as OK (empty list with code 1 passes) while failing on explicit API errors.

Solutions

  1. Read host/code/msg embedded in the error — a consistent upstream msg means site-side trouble; wait or rely on other mirrors.
  2. If the site changed its success convention (e.g. code 200), update the `resp.Code != 1` check in qiwei.go to match the new contract.
  3. Confirm with curl that a known-good keyword returns code 1; if yes, the failure is keyword-specific, not environmental.
  4. Treat as transient: searchSuggestWithFallback will try remaining hosts, and pansou merges results from other plugins.
Defensive patterns

Strategy: retry

Validate before calling

// pre-check parsed response before treating it as an error
if resp.Code == 1 || len(resp.List) > 0 {
    return resp.List, nil // healthy response
}
// otherwise it's the abnormal-code path; retry next host

Try / catch

items, err := p.searchSuggest(client, host, keyword)
if err != nil && strings.Contains(err.Error(), "suggest 响应异常") {
    log.Printf("qiwei upstream API error on %s: %v; trying next host", host, err)
    continue
}

Prevention

When it happens

Trigger: The endpoint returns JSON like {"code":0,"msg":"...","list":[]} — non-1 code with zero items. Fired by the check `if resp.Code != 1 && len(resp.List) == 0` after successful unmarshal.

Common situations: Upstream API degraded or returning its own error codes (maintenance, DB issues); anti-bot returning JSON-form errors; extremely rare keyword edge cases triggering server-side errors; the site changed its success code convention from 1 to something else.

Understand the failure class

Background: "invalid response format", "malformed payload", "missing data field": when an API returns 200 but the response shape is wrong — this error's family across 23 libraries.

Related errors


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

Appendix: source

Thrown at plugin/qiwei/qiwei.go:214

		if err := p.solveVerification(client, searchURL, body); err != nil {
			return nil, fmt.Errorf("[%s] 搜索验证失败: %w", p.Name(), err)
		}
		body, err = p.fetchBody(client, searchURL, host+"/", searchTimeout)
		if err != nil {
			return nil, err
		}
		if isVerifyPage(body) {
			return nil, fmt.Errorf("[%s] 命中验证页: %s", p.Name(), host)
		}
	}

	var resp suggestResponse
	if err := json.Unmarshal([]byte(body), &resp); err != nil {
		return nil, fmt.Errorf("[%s] suggest 响应解析失败: %w", p.Name(), err)
	}

	if resp.Code != 1 && len(resp.List) == 0 {
		return nil, fmt.Errorf("[%s] suggest 响应异常: host=%s code=%d msg=%s", p.Name(), host, resp.Code, resp.Msg)
	}

	return resp.List, nil
}

func (p *QiweiPlugin) enrichResults(client *http.Client, host string, items []suggestItem, forceRefresh bool) []model.SearchResult {
	results := make([]model.SearchResult, len(items))
	var wg sync.WaitGroup
	sem := make(chan struct{}, maxConcurrent)

	for i, item := range items {
		wg.Add(1)
		go func(idx int, it suggestItem) {
			defer wg.Done()
			sem <- struct{}{}
			defer func() { <-sem }()

			results[idx] = p.buildResult(client, host, it, forceRefresh)

View on GitHub (pinned to beaa561337)