{"record":{"id":"106ae13d3cfc212e","repo":"fish2018/pansou","slug":"s-w-106ae1","errorCode":null,"errorMessage":"[%s] 创建请求失败: %w","messagePattern":"\\[(.+?)\\] 创建请求失败: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"plugin/labi/labi.go","lineNumber":184,"sourceCode":"\n\t// 5. 异步获取详情页信息\n\tenhancedResults := p.enhanceWithDetails(client, results, selectedBase)\n\n\t// 6. 关键词过滤\n\treturn plugin.FilterResultsByKeyword(enhancedResults, keyword), nil\n}\n\nfunc (p *LabiAsyncPlugin) searchAtBase(client *http.Client, keyword, baseURL string) ([]model.SearchResult, error) {\n\tsearchURL := fmt.Sprintf(\"%s/index.php/vod/search/wd/%s.html\", strings.TrimRight(baseURL, \"/\"), url.QueryEscape(keyword))\n\n\t// 2. 创建带超时的上下文\n\tctx, cancel := context.WithTimeout(context.Background(), DefaultTimeout)\n\tdefer cancel()\n\n\t// 3. 创建请求\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\n\t// 4. 设置完整的请求头（避免反爬虫）\n\treq.Header.Set(\"User-Agent\", \"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36\")\n\treq.Header.Set(\"Accept\", \"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8\")\n\treq.Header.Set(\"Accept-Language\", \"zh-CN,zh;q=0.9,en;q=0.8\")\n\treq.Header.Set(\"Connection\", \"keep-alive\")\n\treq.Header.Set(\"Upgrade-Insecure-Requests\", \"1\")\n\treq.Header.Set(\"Cache-Control\", \"max-age=0\")\n\treq.Header.Set(\"Referer\", strings.TrimRight(baseURL, \"/\")+\"/\")\n\n\t// 5. 发送请求（带重试机制）\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","sourceCodeStart":166,"sourceCodeEnd":202,"githubUrl":"https://github.com/fish2018/pansou/blob/beaa56133755a548ebc51b090b3816e2ae044aa6/plugin/labi/labi.go#L166-L202","documentation":"In labi's searchAtBase, http.NewRequestWithContext failed while building the GET request for the given mirror's search URL. The request never left the machine; the URL string itself was rejected by net/http (bad scheme, invalid characters, unparseable host).","triggerScenarios":"http.NewRequestWithContext(ctx, \"GET\", searchURL, nil) errors because searchURL built from baseURL plus the keyword is malformed — e.g. baseURL missing scheme, keyword containing spaces/control characters, or an empty URL string.","commonSituations":"A mirror base URL configured or hard-coded without 'https://', keyword not url.QueryEscape'd before joining the search path, whitespace/newline in a scraped base URL.","solutions":["URL-encode the keyword (url.QueryEscape) before building searchURL","Trim and validate baseURL (strings.TrimSpace, must start with http:// or https://) before constructing the request","Log the exact searchURL next to the wrapped error to see the offending string","Fix or remove the broken mirror entry from the base list"],"exampleFix":"// before\nsearchURL := baseURL + \"/search.php?searchname=\" + keyword\n// after\nsearchURL := strings.TrimRight(baseURL, \"/\") + \"/search.php?searchname=\" + url.QueryEscape(keyword)","handlingStrategy":"validation","validationCode":"if !strings.HasPrefix(strings.TrimSpace(baseURL), \"http\") || url.QueryEscape(keyword) == \"\" {\n    // reject before searchAtBase builds the request\n}","typeGuard":"func validBaseURL(s string) bool {\n    u, err := url.Parse(strings.TrimSpace(s))\n    return err == nil && (u.Scheme == \"http\" || u.Scheme == \"https\") && u.Host != \"\"\n}","tryCatchPattern":"if err != nil {\n    var urlErr *url.Error\n    if errors.As(err, &urlErr) {\n        log.Printf(\"invalid mirror URL %q: %v\", urlErr.URL, urlErr.Err)\n    }\n    return nil\n}","preventionTips":["Validate every mirror base URL (scheme+host) when loading the source list","url.QueryEscape all keywords and query values","TrimSpace URLs scraped from pages or config","Unit-test URL construction with edge-case keywords (spaces, CJK, quotes)"],"tags":["network","http","url","scraping"],"backgroundTag":"invalid-url-format","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"}