fish2018/pansou · error
[ ] 解码搜索结果失败
Error message
[%s] 解码搜索结果失败: %w
What it means
The raw response bytes could not be converted from GB18030 to UTF-8 by decodeGB18030, so the plugin cannot proceed to HTML parsing. This means the body is not valid GB18030 — typically because the site changed its encoding (e.g. now serving UTF-8) or returned compressed/binary/garbage content. The wrapped error comes from the GB18030 decoder (golang.org/x/text).
Solutions
- Check the response's Content-Type charset and <meta charset> to confirm the actual encoding; update decodeGB18030 usage if the site switched to UTF-8.
- Ensure gzip handling: set Accept-Encoding explicitly or wrap resp.Body with gzip.NewReader when Content-Encoding is gzip.
- Inspect the first bytes of the body (hex dump) to detect compressed or binary content.
- Fall back to decoding as UTF-8 when GB18030 decoding fails.
Example fix
// before
decoded, err := decodeGB18030(body)
if err != nil {
return nil, fmt.Errorf("[%s] 解码搜索结果失败: %w", p.Name(), err)
}
// after
decoded, err := decodeGB18030(body)
if err != nil {
if utf8.Valid(body) {
decoded = string(body) // site switched to UTF-8
} else {
return nil, fmt.Errorf("[%s] 解码搜索结果失败: %w", p.Name(), err)
}
} Defensive patterns
Strategy: fallback
Validate before calling
if !utf8.Valid(body) && !looksLikeGB18030(body) {
return fmt.Errorf("body is neither valid UTF-8 nor GB18030")
} Type guard
func isUTF8(b []byte) bool { return utf8.Valid(b) } Try / catch
decoded, err := decodeGB18030(body)
if err != nil {
if utf8.Valid(body) { decoded = string(body) } else { return nil, fmt.Errorf("[%s] 解码搜索结果失败: %w", p.Name(), err) }
} Prevention
- Detect charset from Content-Type / <meta charset> instead of hardcoding GB18030
- Handle Content-Encoding: gzip before decoding
- Fall back to UTF-8 when GB18030 decoding fails
- Keep golang.org/x/text/encoding/simplifiedchinese up to date
When it happens
Trigger: decodeGB18030(body) errors in fetchSearch: body bytes are not decodable as GB18030 — the site switched to UTF-8, the response is gzip/deflate that was not decompressed, or a CAPTCHA/binary page was returned instead of HTML.
Common situations: Target site migrated to UTF-8 while the plugin still assumes GB18030; a reverse proxy or CDN serving compressed content without the plugin requesting/handling it; an HTML error or challenge page with bytes the decoder rejects.
Related errors
AI-assisted analysis of fish2018/pansou@beaa561337 (2026-09-07).
Data as JSON: /api/errors/d7380ae349c2e17d.
Report an issue: GitHub.
Appendix: source
Thrown at plugin/dygang/dygang.go:193
return nil, fmt.Errorf("[%s] 创建搜索请求失败: %w", p.Name(), err)
}
setHeaders(req, baseURL+"/")
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
resp, err := client.Do(req)
if err != nil {
return nil, fmt.Errorf("[%s] 搜索请求失败: %w", p.Name(), err)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("[%s] 搜索请求返回 HTTP %d", p.Name(), resp.StatusCode)
}
body, err := io.ReadAll(io.LimitReader(resp.Body, 4<<20))
if err != nil {
return nil, fmt.Errorf("[%s] 读取搜索结果失败: %w", p.Name(), err)
}
decoded, err := decodeGB18030(body)
if err != nil {
return nil, fmt.Errorf("[%s] 解码搜索结果失败: %w", p.Name(), err)
}
doc, err := goquery.NewDocumentFromReader(strings.NewReader(decoded))
if err != nil {
return nil, fmt.Errorf("[%s] 解析搜索结果失败: %w", p.Name(), err)
}
return doc, nil
}
func (p *Plugin) fetchDetail(client *http.Client, detailURL string) ([]magnetItem, string, string) {
ctx, cancel := context.WithTimeout(context.Background(), requestTimeout)
defer cancel()
req, err := http.NewRequestWithContext(ctx, http.MethodGet, detailURL, nil)
if err != nil {
return nil, "", ""
}
setHeaders(req, baseURL+"/")
resp, err := client.Do(req)
if err != nil {View on GitHub (pinned to beaa561337)