{"record":{"id":"7b5194041bd1d181","repo":"fish2018/pansou","slug":"s-w-7b5194","errorCode":null,"errorMessage":"[%s] 获取接口配置失败: %w","messagePattern":"\\[(.+?)\\] 获取接口配置失败: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"plugin/yingso/yingso.go","lineNumber":193,"sourceCode":"\tfor index, result := range resolved {\n\t\tif !valid[index] || len(result.Links) == 0 {\n\t\t\tcontinue\n\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{","sourceCodeStart":175,"sourceCodeEnd":211,"githubUrl":"https://github.com/fish2018/pansou/blob/beaa56133755a548ebc51b090b3816e2ae044aa6/plugin/yingso/yingso.go#L175-L211","documentation":"fetchConfig calls GET {apiBaseURL}/test via requestJSON to obtain the API configuration envelope; if that request fails at the transport/decoding level, the error is wrapped as 获取接口配置失败. This is a bootstrap step — search cannot proceed without the config (e.g. a key extracted from the XOR-decoded Data).","triggerScenarios":"The GET to p.apiBaseURL+\"/test\" failed: connection refused/timeout, non-2xx status, or the response body could not be decoded into apiEnvelope[string] by requestJSON.","commonSituations":"Wrong or outdated apiBaseURL in the plugin config; upstream /test endpoint moved or was removed; firewall/proxy blocks the request; upstream serving an HTML error page instead of the expected envelope.","solutions":["Verify apiBaseURL is correct and reachable (curl {apiBaseURL}/test).","Inspect the wrapped error from requestJSON for connection vs decode details.","Update the plugin/config if the upstream endpoint changed.","Add a timeout and retry for transient network failures."],"exampleFix":"// before\nif err := p.requestJSON(ctx, client, http.MethodGet, p.apiBaseURL+\"/test\", nil, &response); err != nil {\n    return apiConfig{}, fmt.Errorf(\"[%s] 获取接口配置失败: %w\", p.Name(), err)\n}\n// after\nendpoint := strings.TrimRight(p.apiBaseURL, \"/\") + \"/test\"\nif err := p.requestJSON(ctx, client, http.MethodGet, endpoint, nil, &response); err != nil {\n    return apiConfig{}, fmt.Errorf(\"[%s] 获取接口配置失败: %w (endpoint: %s)\", p.Name(), err, endpoint)\n}","handlingStrategy":"try-catch","validationCode":"// Go: validate config before calling\nif p.apiBaseURL == \"\" {\n    return fmt.Errorf(\"apiBaseURL is not configured\")\n}\nu, err := url.Parse(p.apiBaseURL)\nif err != nil || u.Scheme == \"\" || u.Host == \"\" {\n    return fmt.Errorf(\"invalid apiBaseURL: %q\", p.apiBaseURL)\n}","typeGuard":null,"tryCatchPattern":"cfg, err := fetchConfig(ctx, client)\nif err != nil {\n    if strings.Contains(err.Error(), \"获取接口配置失败\") {\n        log.Printf(\"Yingso config endpoint unreachable, retrying: %v\", err)\n        return fetchConfigWithRetry(ctx, client, 3)\n    }\n    return err\n}","preventionTips":["Verify apiBaseURL with curl after every config change.","Set explicit HTTP timeouts on the client.","Retry the bootstrap /test call a few times on startup.","Alert on repeated config-fetch failures rather than silently failing searches."],"tags":["http","config","network"],"backgroundTag":"http-request-failed","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"}