fish2018/pansou · error
[ ] Cloudflare 请求客户端未初始化
Error message
[%s] Cloudflare 请求客户端未初始化
What it means
The Diduan plugin relies on a cloudscraper client (p.scraper) initialized during plugin setup to bypass Cloudflare. searchImpl returns this error immediately when p.scraper is nil, meaning the Cloudflare-capable client was never constructed successfully.
Solutions
- Check plugin startup logs for the cloudscraper initialization error and fix the root cause.
- Ensure the plugin's Init/constructor that creates p.scraper runs before any search is issued.
- Validate scraper-related configuration (proxy, browser emulation options) is present and valid.
- Add a startup health check that fails fast if p.scraper is nil instead of failing at search time.
Example fix
// before
p := &DiduanPlugin{}
results, err := p.Search(keyword) // fails: scraper nil
// after
p := NewDiduanPlugin()
if err := p.Init(cfg); err != nil { log.Fatalf("init: %v", err) }
results, err := p.Search(keyword) Defensive patterns
Strategy: validation
Validate before calling
if p.scraper == nil {
return errors.New("diduan plugin not initialized: scraper is nil")
}
// safe to search Try / catch
if err != nil {
if strings.Contains(err.Error(), "未初始化") {
return fmt.Errorf("re-init plugin before searching: %w", err)
}
return err
} Prevention
- Always run plugin Init and check its error before issuing searches.
- Add a startup assertion that required clients (scraper) are non-nil.
- Construct plugins through factory functions, not raw struct literals.
When it happens
Trigger: p.searchImpl is invoked (via AsyncSearchWithResult) but plugin initialization failed or was skipped, leaving p.scraper nil — e.g. the cloudscraper constructor returned an error that was ignored or logged only.
Common situations: Missing dependencies or options for initializing the scraper at startup; plugin constructed directly in tests without calling the init routine; an earlier init failure (bad proxy config, missing browser fingerprint data) left the scraper unset.
Related errors
AI-assisted analysis of fish2018/pansou@beaa561337 (2026-09-07).
Data as JSON: /api/errors/43fc027bd139fd58.
Report an issue: GitHub.
Appendix: source
Thrown at plugin/diduan/diduan.go:130
// Search 搜索接口
func (p *DiduanPlugin) Search(keyword string, ext map[string]interface{}) ([]model.SearchResult, error) {
result, err := p.SearchWithResult(keyword, ext)
if err != nil {
return nil, err
}
return result.Results, nil
}
// SearchWithResult 使用 BaseAsyncPlugin 的缓存和后台刷新能力。
func (p *DiduanPlugin) SearchWithResult(keyword string, ext map[string]interface{}) (model.PluginSearchResult, error) {
return p.AsyncSearchWithResult(keyword, p.searchImpl, p.MainCacheKey, ext)
}
// searchImpl 搜索实现
func (p *DiduanPlugin) searchImpl(client *http.Client, keyword string, ext map[string]interface{}) ([]model.SearchResult, error) {
if p.scraper == nil {
return nil, fmt.Errorf("[%s] Cloudflare 请求客户端未初始化", p.Name())
}
if p.debugMode {
log.Printf("[DIDUAN] 开始搜索: %s", keyword)
}
// 第一步:执行搜索获取结果列表
searchResults, err := p.executeSearch(keyword)
if err != nil {
return nil, fmt.Errorf("[%s] 执行搜索失败: %w", p.Name(), err)
}
if p.debugMode {
log.Printf("[DIDUAN] 搜索获取到 %d 个结果", len(searchResults))
}
// 第二步:并发获取详情页链接
finalResults := p.fetchDetailLinks(searchResults, keyword)
View on GitHub (pinned to beaa561337)