fish2018/pansou · error

[ ] 接口配置异常: code= msg=

Error message

[%s] 接口配置异常: code=%d msg=%s

What it means

The Yingso plugin's bootstrap call to GET /test returned a non-200 code or an empty encrypted payload, so fetchConfig cannot obtain the API configuration (URLVersion, UserID, Start/End window). The plugin wraps this in a named error including the upstream code and message so callers can see the remote API rejected the bootstrap request.

Solutions

  1. Verify p.apiBaseURL points to the correct, reachable Yingso API host and the /test endpoint exists there
  2. Log/inspect response.Code and response.Msg to identify the upstream error and address it (auth, rate limit, maintenance)
  3. Retry after confirming the upstream service is healthy
  4. If the API contract changed, update requestJSON/envelope handling to match the new response shape

Example fix

// before
p := NewYingsoPlugin(WithAPIBaseURL("https://wrong-host.example"))
// after
p := NewYingsoPlugin(WithAPIBaseURL("https://yingso-api.example.com"))
Defensive patterns

Strategy: try-catch

Validate before calling

u, err := url.Parse(apiBaseURL)
if err != nil || u.Scheme == "" || u.Host == "" {
    return fmt.Errorf("invalid apiBaseURL: %q", apiBaseURL)
}

Try / catch

cfg, err := p.fetchConfig(ctx, client)
if err != nil {
    var apiErr *APIError
    if errors.As(err, &apiErr) {
        log.Printf("yingso bootstrap rejected: code=%d msg=%s", apiErr.Code, apiErr.Msg)
    }
    return retry.WithBackoff(ctx, 3, p.fetchConfig, ctx, client)
}

Prevention

When it happens

Trigger: p.requestJSON succeeds at the HTTP level but response.Code != http.StatusOK, or response.Code is 200 while response.Data is an empty string, when calling p.apiBaseURL+"/test" from fetchConfig.

Common situations: The Yingso API base URL is misconfigured or points at a gateway that returns an error page; the upstream service is degraded or rate-limiting and replies with a non-200 envelope; the remote endpoint changed its bootstrap contract and returns 200 with no data payload.

Understand the failure class

Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.

Related errors


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

Appendix: source

Thrown at plugin/yingso/yingso.go:196

		}
		linkKey := result.Links[0].URL + "\x00" + result.Links[0].Password
		if _, exists := seen[linkKey]; exists {
			continue
		}
		seen[linkKey] = struct{}{}
		results = append(results, result)
	}

	return plugin.FilterResultsByKeyword(results, keyword), nil
}

func (p *YingsoPlugin) fetchConfig(ctx context.Context, client *http.Client) (apiConfig, error) {
	var response apiEnvelope[string]
	if err := p.requestJSON(ctx, client, http.MethodGet, p.apiBaseURL+"/test", nil, &response); err != nil {
		return apiConfig{}, fmt.Errorf("[%s] 获取接口配置失败: %w", p.Name(), err)
	}
	if response.Code != http.StatusOK || response.Data == "" {
		return apiConfig{}, fmt.Errorf("[%s] 接口配置异常: code=%d msg=%s", p.Name(), response.Code, response.Msg)
	}

	decoded := xorUTF16(response.Data, bootstrapKey)
	var config apiConfig
	if err := jsonutil.UnmarshalString(decoded, &config); err != nil {
		return apiConfig{}, fmt.Errorf("[%s] 解析接口配置失败: %w", p.Name(), err)
	}
	if config.URLVersion == "" || config.UserID == "" || config.Start < 0 || config.End <= config.Start || config.End > 24 {
		return apiConfig{}, fmt.Errorf("[%s] 接口配置缺少必要字段", p.Name())
	}
	return config, nil
}

func (p *YingsoPlugin) search(ctx context.Context, client *http.Client, config apiConfig, keyword string) ([]searchItem, error) {
	payload := searchPayload{
		PageSize: pageSize,
		PageNum:  1,
		Title:    keyword,

View on GitHub (pinned to beaa561337)