fish2018/pansou · error

[ ] 搜索接口返回失败

Error message

[%s] 搜索接口返回失败

What it means

The JSON decoded successfully but the payload's OK flag is false, meaning the Lou1 search API itself reported a business-logic failure. The plugin treats this as an explicit upstream rejection of the search.

Solutions

  1. Log the full payload — many APIs include an error message alongside ok=false
  2. Check whether the API now requires auth/keys and add them to headers
  3. Verify the API endpoint version is still supported; migrate if deprecated
  4. Inspect request parameters (keyword, page, limit) for values the API rejects

Example fix

// before
if !payload.OK { return nil, fmt.Errorf("search failed") }
// after
if !payload.OK {
    return nil, fmt.Errorf("lou1 api failure: code=%d msg=%s", payload.Code, payload.Message)
}
Defensive patterns

Strategy: fallback

Try / catch

results, err := lou1.Search(kw)
if err != nil && strings.Contains(err.Error(), "搜索接口返回失败") {
    log.Printf("lou1 api rejected search; payload msg: %v", payloadMsg(err))
    return tryAlternatePlugins(kw)
}

Prevention

When it happens

Trigger: jsonutil.Unmarshal succeeds, then payload.OK == false — the API responded but with an error/failure status in the envelope.

Common situations: Keyword violates upstream search constraints; API key/token absent or expired; search endpoint deprecated in favor of a new version; upstream rate limiting surfaced as an in-band failure flag.

Related errors


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

Appendix: source

Thrown at plugin/lou1/lou1.go:210

		return nil, fmt.Errorf("[%s] 搜索请求失败: %w", p.Name(), err)
	}
	defer resp.Body.Close()

	if resp.StatusCode != http.StatusOK {
		return nil, fmt.Errorf("[%s] 搜索返回状态码: %d", p.Name(), resp.StatusCode)
	}

	body, err := io.ReadAll(resp.Body)
	if err != nil {
		return nil, fmt.Errorf("[%s] 读取搜索响应失败: %w", p.Name(), err)
	}

	var payload lou1SearchResponse
	if err := jsonutil.Unmarshal(body, &payload); err != nil {
		return nil, fmt.Errorf("[%s] 解析搜索 JSON 失败: %w", p.Name(), err)
	}
	if !payload.OK {
		return nil, fmt.Errorf("[%s] 搜索接口返回失败", p.Name())
	}

	threads := make([]searchThread, 0, minInt(searchLimit, len(payload.Data.Hits)))
	for _, hit := range payload.Data.Hits {
		if len(threads) >= searchLimit {
			break
		}
		title := strings.TrimSpace(hit.Subject)
		threadURL := toAbsoluteURL(hit.ThreadURL)
		if title == "" || threadURL == "" {
			continue
		}
		threads = append(threads, searchThread{
			Title: title,
			URL:   threadURL,
		})
	}
	return threads, nil

View on GitHub (pinned to beaa561337)