fish2018/pansou · error

[ ] 创建搜索会话请求失败

Error message

[%s] 创建搜索会话请求失败: %w

What it means

ensureSearchSession wraps errors from http.NewRequestWithContext when constructing the GET request to the /api/search/session endpoint used to establish cookies/session state before searching. Construction errors indicate a malformed URL for the session endpoint.

Solutions

  1. Unwrap the error to see the URL parse failure detail.
  2. Validate jupansouBaseURL parses cleanly: url.Parse(jupansouBaseURL) and check scheme/host.
  3. Fix or update the base URL constant to match the current upstream.
  4. Verify no environment-specific override injects a bad base URL.

Example fix

// before: possibly malformed base
base := os.Getenv("JUPANSOU_BASE")
// after: validate before use
u, err := url.Parse(base)
if err != nil || u.Scheme == "" || u.Host == "" {
    return fmt.Errorf("invalid JUPANSOU_BASE: %q", base)
}
Defensive patterns

Strategy: validation

Validate before calling

u, err := url.Parse(jupansouBaseURL)
if err != nil || u.Scheme == "" || u.Host == "" {
    return fmt.Errorf("jupansouBaseURL invalid: %q", jupansouBaseURL)
}
sessionURL := u.Scheme + "://" + u.Host + "/api/search/session"
if _, err := url.Parse(sessionURL); err != nil { return err }

Try / catch

if err := p.ensureSearchSession(client); err != nil && strings.Contains(err.Error(), "创建搜索会话请求失败") {
    log.Printf("session request could not be constructed, check base URL: %v", err)
}

Prevention

When it happens

Trigger: http.NewRequestWithContext fails building the GET to jupansouBaseURL+"/api/search/session" — i.e. jupansouBaseURL is empty, malformed, or contains invalid characters.

Common situations: Misconfigured or empty base URL constant; trailing whitespace/newline in the base URL; upstream moved the session endpoint so a hand-edited URL is invalid.

Understand the failure class

Background: "Invalid URL" errors: why new URL(), URI.parse, and reqwest::Url reject your string — missing scheme, whitespace, and bad path format — this error's family across 39 libraries.

Related errors


AI-assisted analysis of fish2018/pansou@beaa561337 (2026-09-07). Data as JSON: /api/errors/74e4f04929ef2b9a. Report an issue: GitHub.

Appendix: source

Thrown at plugin/jupansou/jupansou.go:175

	// exchanging encrypted URLs to avoid unnecessary transfer requests.
	keywordLower := strings.ToLower(strings.TrimSpace(keyword))
	filteredItems := items[:0]
	for _, item := range items {
		if keywordLower == "" || strings.Contains(strings.ToLower(item.Title), keywordLower) {
			filteredItems = append(filteredItems, item)
		}
	}

	results := p.exchangeItems(client, filteredItems)
	return plugin.FilterResultsByKeyword(results, keyword), nil
}

func (p *JuPansouPlugin) ensureSearchSession(client *http.Client) error {
	ctx, cancel := context.WithTimeout(context.Background(), jupansouTimeout)
	defer cancel()
	req, err := http.NewRequestWithContext(ctx, http.MethodGet, jupansouBaseURL+"/api/search/session", nil)
	if err != nil {
		return fmt.Errorf("[%s] 创建搜索会话请求失败: %w", p.Name(), err)
	}
	req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 Chrome/124.0 Safari/537.36")
	req.Header.Set("Accept", "application/json")
	req.Header.Set("Referer", jupansouBaseURL+"/")
	req.Header.Set("X-Requested-With", "XMLHttpRequest")
	resp, err := client.Do(req)
	if err != nil {
		return fmt.Errorf("[%s] 搜索会话请求失败: %w", p.Name(), err)
	}
	defer resp.Body.Close()
	if resp.StatusCode != http.StatusOK {
		return fmt.Errorf("[%s] 搜索会话返回状态码: %d", p.Name(), resp.StatusCode)
	}
	return nil
}

func (p *JuPansouPlugin) exchangeItems(client *http.Client, items []juPansouStreamItem) []model.SearchResult {
	results := make([]model.SearchResult, 0, len(items))

View on GitHub (pinned to beaa561337)