fish2018/pansou · error
create request failed
Error message
create request failed: %w
What it means
searchPage failed at http.NewRequestWithContext, meaning the outbound POST to the yunso search API could not be constructed. Because the URL is built from a fixed template plus query parameters, this almost always indicates a malformed URL (bad characters in params.Encode() output) or a nil/invalid context.
Solutions
- Log the constructed searchURL and verify it parses (url.Parse)
- Check the incoming ctx is not already canceled before calling searchPage
- Validate yunsoSearchAPI constant is a complete, valid absolute URL
- Use url.Values encoding for the keyword instead of raw concatenation
Example fix
// before
req, err := http.NewRequestWithContext(ctx, http.MethodPost, searchURL, nil)
if err != nil {
return nil, fmt.Errorf("create request failed: %w", err)
}
// after
if err := ctx.Err(); err != nil {
return nil, fmt.Errorf("context canceled before request: %w", err)
}
if _, perr := url.Parse(searchURL); perr != nil {
return nil, fmt.Errorf("invalid search url %q: %w", searchURL, perr)
}
req, err := http.NewRequestWithContext(ctx, http.MethodPost, searchURL, nil)
if err != nil {
return nil, fmt.Errorf("create request failed: %w", err)
} Defensive patterns
Strategy: validation
Validate before calling
u, err := url.Parse(searchURL)
if err != nil || u.Scheme == "" || u.Host == "" {
return fmt.Errorf("invalid search url: %q", searchURL)
}
if ctx.Err() != nil {
return ctx.Err()
} Type guard
func validURL(s string) bool {
u, err := url.Parse(s)
return err == nil && u.Scheme != "" && u.Host != ""
} Try / catch
items, err := searchPage(ctx, client, keyword, page)
if err != nil && strings.Contains(err.Error(), "create request failed") {
log.Error("bad request construction", "err", err)
return ErrBadConfig
} Prevention
- Always build URLs with url.Values/url.PathEscape, never raw string concat
- Validate the base URL constant once at plugin init
- Check ctx.Err() before issuing requests
When it happens
Trigger: http.NewRequestWithContext returns an error when constructing the request to yunsoSearchAPI — e.g. invalid URL syntax after appending encoded params, or a canceled context passed in.
Common situations: Keyword or config value introduces characters that break URL construction, a parent context is already canceled before the request is built, or the API base URL constant was edited incorrectly.
Understand the failure class
Background: "Invalid URL" / "URL cannot be empty": fix the malformed or missing URL behind request-construction failures — this error's family across 50 libraries.
Related errors
AI-assisted analysis of fish2018/pansou@beaa561337 (2026-09-07).
Data as JSON: /api/errors/1cf6beea591c9155.
Report an issue: GitHub.
Appendix: source
Thrown at plugin/yunso/yunso.go:158
func (p *YunsoAsyncPlugin) searchPage(client *http.Client, keyword string, page int) ([]YunsoItem, error) {
ctx, cancel := context.WithTimeout(context.Background(), yunsoDefaultTimeout)
defer cancel()
params := url.Values{}
params.Set("requestID", "")
params.Set("mode", yunsoDefaultMode)
params.Set("scope_content", yunsoDefaultScope)
params.Set("stype", "")
params.Set("wd", keyword)
params.Set("uk", "")
params.Set("page", strconv.Itoa(page))
params.Set("limit", strconv.Itoa(yunsoDefaultPageSize))
params.Set("screen_filetype", "")
searchURL := yunsoSearchAPI + "?" + params.Encode()
req, err := http.NewRequestWithContext(ctx, http.MethodPost, searchURL, nil)
if err != nil {
return nil, fmt.Errorf("create request failed: %w", err)
}
referer := yunsoSearchPage + "?wd=" + url.QueryEscape(keyword)
req.Header.Set("Accept", "application/json, text/plain, */*")
req.Header.Set("Accept-Language", "zh-CN,zh;q=0.9,en;q=0.8")
req.Header.Set("Origin", "https://www.yunso.net")
req.Header.Set("Referer", referer)
req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36")
req.Header.Set("X-Requested-With", "XMLHttpRequest")
resp, err := client.Do(req)
if err != nil {
return nil, fmt.Errorf("request failed: %w", err)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("unexpected status code: %d", resp.StatusCode)View on GitHub (pinned to beaa561337)