fish2018/pansou · error
[ ] 搜索接口异常: code= msg=
Error message
[%s] 搜索接口异常: code=%d msg=%s
What it means
This error is returned by YingsoPlugin.search when the Yingso /search endpoint responds with a valid JSON envelope whose code field is not 200. The HTTP request itself succeeded and the body parsed, but the Yingso API rejected the search request; the API's own code and msg are surfaced for diagnosis.
Solutions
- Log response.Code and response.Msg from the error to identify the API's stated reason and match it against the Yingso API contract.
- Re-fetch the bootstrap config (fetchConfig /test) — a stale url_version or user_id is the most common cause — and retry the search.
- Retry the request after a short backoff; code values like 429 or 5xx in the envelope indicate transient throttling or upstream trouble.
- Verify the request payload matches the current Yingso searchPayload schema; if the API changed fields, update searchPayload/encryptPayload.
- If the API is permanently rejecting requests (e.g. endpoint deprecated), disable the yingso plugin or update defaultAPIBaseURL.
Example fix
// before
if response.Code != http.StatusOK {
return nil, fmt.Errorf("[%s] 搜索接口异常: code=%d msg=%s", p.Name(), response.Code, response.Msg)
}
// after
if response.Code != http.StatusOK {
if response.Code == http.StatusTooManyRequests {
// retry with backoff before giving up
return p.search(ctx, client, config, keyword)
}
return nil, fmt.Errorf("[%s] 搜索接口异常: code=%d msg=%s", p.Name(), response.Code, response.Msg)
} Defensive patterns
Strategy: retry
Validate before calling
if code, msg := yingsoProbeSearch(client); code != 200 {
log.Printf("yingso unavailable: code=%d msg=%s", code, msg)
} Try / catch
results, err := plugin.Search(keyword, ext)
if err != nil {
var apiErr string
if strings.Contains(err.Error(), "搜索接口异常") {
apiErr = "yingso api rejected request; re-fetching config and retrying"
}
log.Println(apiErr, err)
time.Sleep(backoff)
results, err = plugin.Search(keyword, ext)
} Prevention
- Call fetchConfig fresh before searching so url_version/user_id are current.
- Wrap searches in retry with backoff for transient API codes.
- Monitor the error's code=%d value and alert on systematic changes (API contract drift).
- Respect any rate limits; avoid hammering the search endpoint.
When it happens
Trigger: POST to {apiBaseURL}/{url_version}/search returns apiEnvelope with code != 200, e.g. the encrypted payload uses a stale url_version/user_id from fetchConfig, the keyword is rejected/filtered by the API, the API is rate limiting, or the XOR-encrypted request parameters are considered invalid by the server.
Common situations: The Yingso API rotated its url_version so the encrypted payload no longer validates server-side; transient upstream throttling during heavy search load; the API changed its envelope codes; the bootstrap config (user_id) became stale or blocked.
Related errors
AI-assisted analysis of fish2018/pansou@beaa561337 (2026-09-07).
Data as JSON: /api/errors/53856e5e59e3676f.
Report an issue: GitHub.
Appendix: source
Thrown at plugin/yingso/yingso.go:230
PageSize: pageSize,
PageNum: 1,
Title: keyword,
Root: 0,
Category: "all",
UserID: config.UserID,
}
encrypted, err := encryptPayload(payload, config)
if err != nil {
return nil, fmt.Errorf("[%s] 生成搜索参数失败: %w", p.Name(), err)
}
var response apiEnvelope[[]searchItem]
endpoint := fmt.Sprintf("%s/%s/search", p.apiBaseURL, url.PathEscape(config.URLVersion))
if err := p.requestJSON(ctx, client, http.MethodPost, endpoint, encrypted, &response); err != nil {
return nil, fmt.Errorf("[%s] 搜索请求失败: %w", p.Name(), err)
}
if response.Code != http.StatusOK {
return nil, fmt.Errorf("[%s] 搜索接口异常: code=%d msg=%s", p.Name(), response.Code, response.Msg)
}
return response.Data, nil
}
func (p *YingsoPlugin) resolveItem(ctx context.Context, client *http.Client, config apiConfig, item searchItem) (model.SearchResult, error) {
payload := getKeyPayload{ID: item.ID, UserID: config.UserID}
encrypted, err := encryptPayload(payload, config)
if err != nil {
return model.SearchResult{}, err
}
var response apiEnvelope[string]
endpoint := fmt.Sprintf("%s/%s/getKey", p.apiBaseURL, url.PathEscape(config.URLVersion))
if err := p.requestJSON(ctx, client, http.MethodPost, endpoint, encrypted, &response); err != nil {
return model.SearchResult{}, err
}
if response.Code != http.StatusOK || strings.TrimSpace(response.Data) == "" {
return model.SearchResult{}, fmt.Errorf("getKey id=%d code=%d msg=%s", item.ID, response.Code, response.Msg)View on GitHub (pinned to beaa561337)