fish2018/pansou · error
create web search request failed
Error message
create web search request failed: %w
What it means
searchWeb builds the panso.vip web search URL (SousouWebURL + encoded keyword) and creates the request with http.NewRequestWithContext. If request construction fails (malformed URL, bad method, invalid query escaping), this wrapped error is returned before any network I/O happens.
Solutions
- Print/inspect SousouWebURL; ensure it is a valid absolute http(s) URL.
- Validate the URL with url.Parse at plugin init and fail fast with a clear config error.
- Ensure the keyword is passed through url.QueryEscape (it already is) and contains no raw newlines.
- Fix the base URL in the plugin config/source list if the site moved.
Example fix
// before
searchURL := SousouWebURL + "?q=" + url.QueryEscape(strings.TrimSpace(keyword))
req, err := http.NewRequestWithContext(ctx, http.MethodGet, searchURL, nil)
if err != nil {
return nil, fmt.Errorf("create web search request failed: %w", err)
}
// after
base, err := url.Parse(SousouWebURL)
if err != nil || base.Scheme == "" || base.Host == "" {
return nil, fmt.Errorf("invalid SousouWebURL %q: %w", SousouWebURL, err)
}
searchURL := SousouWebURL + "?q=" + url.QueryEscape(strings.TrimSpace(keyword)) Defensive patterns
Strategy: validation
Validate before calling
u, err := url.Parse(SousouWebURL)
if err != nil || u.Scheme == "" || u.Host == "" {
return fmt.Errorf("invalid SousouWebURL: %q", SousouWebURL)
} Try / catch
results, err := plugin.Search(keyword)
if err != nil && strings.Contains(err.Error(), "create web search request failed") {
// config problem: fix SousouWebURL, do not retry
} Prevention
- Validate configured base URLs at plugin startup with url.Parse
- Always require an absolute http(s) URL in config
- Never build URLs by raw concatenation with unescaped user input
- Add a startup smoke-test request per source
When it happens
Trigger: http.NewRequestWithContext(ctx, http.MethodGet, SousouWebURL+"?q="+url.QueryEscape(...), nil) returns err inside searchWeb — almost always an invalid SousouWebURL configuration value.
Common situations: SousouWebURL configured with a typo, missing scheme (e.g. 'panso.vip' without https://), control characters in the URL, or an empty config value.
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/0b8b3d253a35e8d7.
Report an issue: GitHub.
Appendix: source
Thrown at plugin/sousou/sousou.go:178
}
type pansoSearchItem struct {
DocURL string
Title string
Content string
DiskType string
Datetime time.Time
Password string
}
func (p *SousouAsyncPlugin) searchWeb(client *http.Client, keyword string) ([]model.SearchResult, error) {
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
searchURL := SousouWebURL + "?q=" + url.QueryEscape(strings.TrimSpace(keyword))
req, err := http.NewRequestWithContext(ctx, http.MethodGet, searchURL, nil)
if err != nil {
return nil, fmt.Errorf("create web search request failed: %w", err)
}
setSousouWebHeaders(req, "https://www.panso.vip/")
resp, err := client.Do(req)
if err != nil {
return nil, fmt.Errorf("web search request failed: %w", err)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("web search returned status %d", resp.StatusCode)
}
doc, err := goquery.NewDocumentFromReader(resp.Body)
if err != nil {
return nil, fmt.Errorf("parse web search page failed: %w", err)
}
items := make([]pansoSearchItem, 0, 20)
doc.Find("div.search-item").Each(func(_ int, item *goquery.Selection) {View on GitHub (pinned to beaa561337)