{"record":{"id":"3099b50c916c3135","repo":"fish2018/pansou","slug":"w-3099b5","errorCode":null,"errorMessage":"创建搜索请求失败: %w","messagePattern":"创建搜索请求失败: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"plugin/xiaokupan/xiaokupan.go","lineNumber":129,"sourceCode":"\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"构造搜索参数失败: %w\", err)\n\t}\n\n\tendpoint := fmt.Sprintf(\"%s/_serverFn/%s\", strings.TrimRight(p.baseURL, \"/\"), functionID)\n\tparsedEndpoint, err := url.Parse(endpoint)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"解析搜索地址失败: %w\", err)\n\t}\n\tquery := parsedEndpoint.Query()\n\tquery.Set(\"payload\", string(payload))\n\tparsedEndpoint.RawQuery = query.Encode()\n\n\tctx, cancel := context.WithTimeout(context.Background(), requestTimeout)\n\tdefer cancel()\n\n\treq, err := http.NewRequestWithContext(ctx, http.MethodGet, parsedEndpoint.String(), nil)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"创建搜索请求失败: %w\", err)\n\t}\n\tp.setSearchHeaders(req, keyword)\n\n\tbody, err := doLimitedRequest(client, req, maxSearchResponseSize)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn parseSearchResponse(body)\n}\n\nfunc buildSearchPayload(keyword string) ([]byte, error) {\n\tpayload := map[string]interface{}{\n\t\t\"t\": map[string]interface{}{\n\t\t\t\"t\": 10,\n\t\t\t\"i\": 0,\n\t\t\t\"p\": map[string]interface{}{\n\t\t\t\t\"k\": []string{\"data\"},\n\t\t\t\t\"v\": []interface{}{map[string]interface{}{","sourceCodeStart":111,"sourceCodeEnd":147,"githubUrl":"https://github.com/fish2018/pansou/blob/beaa56133755a548ebc51b090b3816e2ae044aa6/plugin/xiaokupan/xiaokupan.go#L111-L147","documentation":"Wraps an error from http.NewRequestWithContext when building the GET request to the xiaokupan search endpoint. Since the URL was already parsed successfully one line earlier, this indicates an invalid method, malformed context, or an invalid URL that passed Parse but fails NewRequest's stricter checks (e.g. nil/invalid URL host).","triggerScenarios":"http.NewRequestWithContext returns an error — usually because the parsed endpoint URL is missing a scheme/host (baseURL like \"xiaokupan.com\" without https:// survives url.Parse but yields an unusable request URL), or the context is invalid.","commonSituations":"baseURL configured without a scheme (\"xiaokupan.com\" instead of \"https://xiaokupan.com\"); endpoint string contains characters NewRequest rejects; programming error passing a canceled context.","solutions":["Check that the final endpoint URL includes scheme and host — a schemeless baseURL is the usual cause","Configure baseURL as a full absolute URL starting with https://","Log parsedEndpoint.String() to see exactly what was passed to NewRequestWithContext","Verify the context passed in is not already canceled"],"exampleFix":"// before\nbaseURL := \"xiaokupan.com\" // schemeless\n// after\nbaseURL := \"https://xiaokupan.com\"","handlingStrategy":"validation","validationCode":"u, _ := url.Parse(endpoint)\nif u.Scheme == \"\" || u.Host == \"\" {\n    return errors.New(\"endpoint missing scheme/host; baseURL must be absolute (https://...)\")\n}","typeGuard":"func isAbsoluteURL(u *url.URL) bool { return u.IsAbs() && u.Host != \"\" }","tryCatchPattern":"req, err := http.NewRequestWithContext(ctx, http.MethodGet, parsedEndpoint.String(), nil)\nif err != nil {\n    log.Printf(\"request build failed for %s: %v\", parsedEndpoint.String(), err)\n    return err\n}","preventionTips":["Ensure baseURL includes scheme and host — schemeless hostnames pass url.Parse but break NewRequest","Validate baseURL at plugin construction time rather than at request time","Log the final endpoint string whenever request construction fails"],"tags":["http","url","request"],"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"}