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

  1. Log the constructed searchURL and verify it parses (url.Parse)
  2. Check the incoming ctx is not already canceled before calling searchPage
  3. Validate yunsoSearchAPI constant is a complete, valid absolute URL
  4. 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

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)