{"record":{"id":"b681dd1690c9110b","repo":"fish2018/pansou","slug":"s-w-b681dd","errorCode":null,"errorMessage":"[%s] 创建搜索请求失败: %w","messagePattern":"\\[(.+?)\\] 创建搜索请求失败: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"plugin/miosou/miosou.go","lineNumber":98,"sourceCode":"func (p *MiosouPlugin) SearchWithResult(keyword string, ext map[string]interface{}) (model.PluginSearchResult, error) {\n\treturn p.AsyncSearchWithResult(keyword, p.searchImpl, p.MainCacheKey, ext)\n}\n\nfunc (p *MiosouPlugin) searchImpl(_ *http.Client, keyword string, _ map[string]interface{}) ([]model.SearchResult, error) {\n\tkeyword = strings.TrimSpace(keyword)\n\tif keyword == \"\" {\n\t\treturn nil, nil\n\t}\n\tif err := p.ensureGate(); err != nil {\n\t\treturn nil, err\n\t}\n\n\tfor attempt := 0; attempt < 2; attempt++ {\n\t\tctx, cancel := context.WithTimeout(context.Background(), requestTimeout)\n\t\treq, err := http.NewRequestWithContext(ctx, http.MethodGet, apiBaseURL+\"/search?keyword=\"+url.QueryEscape(keyword), nil)\n\t\tif err != nil {\n\t\t\tcancel()\n\t\t\treturn nil, fmt.Errorf(\"[%s] 创建搜索请求失败: %w\", p.Name(), err)\n\t\t}\n\t\tsetHeaders(req, \"text/event-stream\")\n\t\tresp, err := p.client.Do(req)\n\t\tif err != nil {\n\t\t\tcancel()\n\t\t\treturn nil, fmt.Errorf(\"[%s] 搜索请求失败: %w\", p.Name(), err)\n\t\t}\n\t\tif isAnubisGateResponse(resp) {\n\t\t\tresp.Body.Close()\n\t\t\tcancel()\n\t\t\tp.invalidateGate()\n\t\t\tif err := p.ensureGate(); err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\t\tif resp.StatusCode != http.StatusOK {\n\t\t\tresp.Body.Close()","sourceCodeStart":80,"sourceCodeEnd":116,"githubUrl":"https://github.com/fish2018/pansou/blob/beaa56133755a548ebc51b090b3816e2ae044aa6/plugin/miosou/miosou.go#L80-L116","documentation":"This error is returned by MiosouPlugin.searchImpl when http.NewRequestWithContext fails to construct the GET request to apiBaseURL + \"/search?keyword=...\". With a constant apiBaseURL this almost always means the URL failed to parse (url.Parse error inside NewRequest) or the context is invalid — a programming/config-level problem rather than a network issue.","triggerScenarios":"searchImpl builds the request on each of its 2 attempts; NewRequestWithContext returns err when the method or URL is invalid — e.g. apiBaseURL was misconfigured to contain spaces or control characters, or the URL is malformed so url.Parse fails.","commonSituations":"A build-time misconfiguration of apiBaseURL (bad constant, env override with whitespace or an invalid scheme); a keyword so unusual it breaks URL construction (rare, since url.QueryEscape is applied); passing a nil/already-canceled context from refactored code.","solutions":["Print the constructed URL and validate it (http.NewRequest manually or url.Parse) to find the malformed part","Check apiBaseURL configuration for stray whitespace, missing scheme, or illegal characters","Ensure the context passed to WithTimeout is fresh, not already canceled","Since this is deterministic, fix the config/code; retrying will not help"],"exampleFix":"// before (misconfigured base)\napiBaseURL = \"miosou.example.com/api\" // missing scheme\n// after\napiBaseURL = \"https://miosou.example.com/api\"\nu, err := url.Parse(apiBaseURL)\nif err != nil || u.Scheme == \"\" {\n    log.Fatalf(\"invalid apiBaseURL: %v\", err)\n}","handlingStrategy":"validation","validationCode":"// Go: validate the API URL at startup\nu, err := url.Parse(apiBaseURL)\nif err != nil || u.Scheme == \"\" || u.Host == \"\" {\n    return fmt.Errorf(\"invalid apiBaseURL %q: %v\", apiBaseURL, err)\n}","typeGuard":"func validHTTPURL(raw string) bool {\n    u, err := url.Parse(raw)\n    return err == nil && (u.Scheme == \"http\" || u.Scheme == \"https\") && u.Host != \"\"\n}","tryCatchPattern":"if req, err = http.NewRequestWithContext(ctx, http.MethodGet, reqURL, nil); err != nil {\n    return nil, fmt.Errorf(\"constructing search request for %q: %w\", reqURL, err)\n}","preventionTips":["Validate baseURL configuration at plugin init, not per-request","Keep URL construction with url.Values and url.QueryEscape","Never build URLs by naive string concatenation of untrusted input","Unit-test request construction with the real constant"],"tags":["http","url","request-construction","configuration"],"backgroundTag":"invalid-url","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"}