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

  1. Log response.Code and response.Msg from the error to identify the API's stated reason and match it against the Yingso API contract.
  2. Re-fetch the bootstrap config (fetchConfig /test) — a stale url_version or user_id is the most common cause — and retry the search.
  3. Retry the request after a short backoff; code values like 429 or 5xx in the envelope indicate transient throttling or upstream trouble.
  4. Verify the request payload matches the current Yingso searchPayload schema; if the API changed fields, update searchPayload/encryptPayload.
  5. 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

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)