{"record":{"id":"cbf48a24f6fae8bb","repo":"fish2018/pansou","slug":"s-code-d-msg-s","errorCode":null,"errorMessage":"[%s] 接口配置异常: code=%d msg=%s","messagePattern":"\\[(.+?)\\] 接口配置异常: code=(.+?) msg=(.+?)","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"plugin/yingso/yingso.go","lineNumber":196,"sourceCode":"\t\t}\n\t\tlinkKey := result.Links[0].URL + \"\\x00\" + result.Links[0].Password\n\t\tif _, exists := seen[linkKey]; exists {\n\t\t\tcontinue\n\t\t}\n\t\tseen[linkKey] = struct{}{}\n\t\tresults = append(results, result)\n\t}\n\n\treturn plugin.FilterResultsByKeyword(results, keyword), nil\n}\n\nfunc (p *YingsoPlugin) fetchConfig(ctx context.Context, client *http.Client) (apiConfig, error) {\n\tvar response apiEnvelope[string]\n\tif err := p.requestJSON(ctx, client, http.MethodGet, p.apiBaseURL+\"/test\", nil, &response); err != nil {\n\t\treturn apiConfig{}, fmt.Errorf(\"[%s] 获取接口配置失败: %w\", p.Name(), err)\n\t}\n\tif response.Code != http.StatusOK || response.Data == \"\" {\n\t\treturn apiConfig{}, fmt.Errorf(\"[%s] 接口配置异常: code=%d msg=%s\", p.Name(), response.Code, response.Msg)\n\t}\n\n\tdecoded := xorUTF16(response.Data, bootstrapKey)\n\tvar config apiConfig\n\tif err := jsonutil.UnmarshalString(decoded, &config); err != nil {\n\t\treturn apiConfig{}, fmt.Errorf(\"[%s] 解析接口配置失败: %w\", p.Name(), err)\n\t}\n\tif config.URLVersion == \"\" || config.UserID == \"\" || config.Start < 0 || config.End <= config.Start || config.End > 24 {\n\t\treturn apiConfig{}, fmt.Errorf(\"[%s] 接口配置缺少必要字段\", p.Name())\n\t}\n\treturn config, nil\n}\n\nfunc (p *YingsoPlugin) search(ctx context.Context, client *http.Client, config apiConfig, keyword string) ([]searchItem, error) {\n\tpayload := searchPayload{\n\t\tPageSize: pageSize,\n\t\tPageNum:  1,\n\t\tTitle:    keyword,","sourceCodeStart":178,"sourceCodeEnd":214,"githubUrl":"https://github.com/fish2018/pansou/blob/beaa56133755a548ebc51b090b3816e2ae044aa6/plugin/yingso/yingso.go#L178-L214","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Verify p.apiBaseURL points to the correct, reachable Yingso API host and the /test endpoint exists there","Log/inspect response.Code and response.Msg to identify the upstream error and address it (auth, rate limit, maintenance)","Retry after confirming the upstream service is healthy","If the API contract changed, update requestJSON/envelope handling to match the new response shape"],"exampleFix":"// before\np := NewYingsoPlugin(WithAPIBaseURL(\"https://wrong-host.example\"))\n// after\np := NewYingsoPlugin(WithAPIBaseURL(\"https://yingso-api.example.com\"))","handlingStrategy":"try-catch","validationCode":"u, err := url.Parse(apiBaseURL)\nif err != nil || u.Scheme == \"\" || u.Host == \"\" {\n    return fmt.Errorf(\"invalid apiBaseURL: %q\", apiBaseURL)\n}","typeGuard":null,"tryCatchPattern":"cfg, err := p.fetchConfig(ctx, client)\nif err != nil {\n    var apiErr *APIError\n    if errors.As(err, &apiErr) {\n        log.Printf(\"yingso bootstrap rejected: code=%d msg=%s\", apiErr.Code, apiErr.Msg)\n    }\n    return retry.WithBackoff(ctx, 3, p.fetchConfig, ctx, client)\n}","preventionTips":["Validate apiBaseURL at plugin construction time","Monitor the /test bootstrap endpoint with a health check","Log response.Code and response.Msg from the envelope before wrapping","Retry non-200 bootstrap responses with backoff"],"tags":["http","api","config","upstream"],"backgroundTag":"http-error-response","analyzedSha":"beaa56133755a548ebc51b090b3816e2ae044aa6","analyzedAt":"2026-09-07T00:31:18.025Z","contentChangedAt":"2026-09-07T00:31:18.025Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}