{"record":{"id":"1ec7ac05a2efc1a1","repo":"fish2018/pansou","slug":"s-w-1ec7ac","errorCode":null,"errorMessage":"[%s] 创建请求失败: %w","messagePattern":"\\[(.+?)\\] 创建请求失败: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"plugin/pianku/pianku.go","lineNumber":132,"sourceCode":"\tif ext != nil {\n\t\tif titleEn, exists := ext[\"title_en\"]; exists {\n\t\t\tif titleEnStr, ok := titleEn.(string); ok && titleEnStr != \"\" {\n\t\t\t\tsearchKeyword = titleEnStr\n\t\t\t}\n\t\t}\n\t}\n\t\n\t// 构建请求URL\n\tsearchURL := fmt.Sprintf(\"%s%s?wd=%s\", BaseURL, SearchPath, url.QueryEscape(searchKeyword))\n\t\n\t// 创建带超时的上下文\n\tctx, cancel := context.WithTimeout(context.Background(), TimeoutSeconds*time.Second)\n\tdefer cancel()\n\t\n\t// 创建请求\n\treq, err := http.NewRequestWithContext(ctx, \"GET\", searchURL, nil)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"[%s] 创建请求失败: %w\", p.Name(), err)\n\t}\n\t\n\t// 设置请求头\n\tp.setRequestHeaders(req)\n\t\n\t// 发送HTTP请求（带重试机制）\n\tresp, err := p.doRequestWithRetry(req, client)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"[%s] 搜索请求失败: %w\", p.Name(), err)\n\t}\n\tdefer resp.Body.Close()\n\t\n\t// 检查状态码\n\tif resp.StatusCode != 200 {\n\t\treturn nil, fmt.Errorf(\"[%s] 请求返回状态码: %d\", p.Name(), resp.StatusCode)\n\t}\n\t\n\t// 解析HTML","sourceCodeStart":114,"sourceCodeEnd":150,"githubUrl":"https://github.com/fish2018/pansou/blob/beaa56133755a548ebc51b090b3816e2ae044aa6/plugin/pianku/pianku.go#L114-L150","documentation":"http.NewRequestWithContext failed while building the GET request for the pianku search URL, so the request was never sent. This only happens with an invalid method/URL/body combination — most commonly a malformed searchURL.","triggerScenarios":"searchURL built from config/base URL that is unparseable (control characters, missing scheme, bad query escaping of the keyword), causing url.Parse to fail inside NewRequestWithContext.","commonSituations":"Misconfigured base URL containing spaces or newlines; keyword with characters that break naive URL concatenation; empty base URL variable in config.","solutions":["Log the constructed searchURL when this error occurs","Validate/escape the keyword with url.QueryEscape before building the URL","Sanity-check the configured base URL (scheme, no whitespace)","If the base URL comes from config, add a startup validation step"],"exampleFix":"// before\nsearchURL := baseURL + \"/s.php?q=\" + keyword\nreq, err := http.NewRequestWithContext(ctx, \"GET\", searchURL, nil)\n// after\nsearchURL := baseURL + \"/s.php?q=\" + url.QueryEscape(keyword)\nif _, perr := url.Parse(searchURL); perr != nil { return nil, fmt.Errorf(\"bad search url %q: %w\", searchURL, perr) }\nreq, err := http.NewRequestWithContext(ctx, \"GET\", searchURL, nil)","handlingStrategy":"validation","validationCode":"u, err := url.Parse(searchURL)\nif err != nil || u.Scheme == \"\" || u.Host == \"\" {\n    return fmt.Errorf(\"invalid search URL %q\", searchURL)\n}","typeGuard":"func validURL(s string) bool {\n    u, err := url.Parse(s)\n    return err == nil && (u.Scheme == \"http\" || u.Scheme == \"https\") && u.Host != \"\"\n}","tryCatchPattern":"results, err := plugin.Search(keyword, ext)\nif err != nil {\n    if strings.Contains(err.Error(), \"创建请求失败\") {\n        // malformed URL/config: fix base URL or keyword escaping, do not retry\n    }\n}","preventionTips":["Escape keywords with url.QueryEscape","Validate configured base URLs at startup","Never interpolate untrusted input into URL strings without escaping"],"tags":["go","http","url","request-construction","plugin"],"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"}