fish2018/pansou · error
[susu] 获取按钮列表失败
Error message
[susu] 获取按钮列表失败: %w
What it means
getLinks wraps errors from doRequestWithRetry when fetching the button-list API endpoint. Like [700], the retried POST to ButtonListURL never produced a response: connection failures, timeouts, or retries exhausted over MaxRetries attempts. The 20-second context timeout also surfaces as this error when exceeded.
Solutions
- Unwrap the error chain to see the root cause (deadline exceeded vs connection refused).
- Raise the 20s context timeout if the API is legitimately slow.
- Confirm the API host is reachable (curl -X POST ButtonListURL with the same form) from the host.
- Check MaxRetries/backoff settings; increase them for flaky networks.
- If the endpoint moved, update ButtonListURL.
Example fix
null
Defensive patterns
Strategy: retry
Validate before calling
conn, err := net.DialTimeout("tcp", apiHost+":443", 5*time.Second)
if err != nil { /* API host unreachable, skip link resolution */ }
conn.Close() Try / catch
links, err := p.getLinks(postID)
if err != nil {
if errors.Is(err, context.DeadlineExceeded) {
// increase timeout or retry with backoff
}
log.Printf("button-list fetch failed: %v", err)
return nil, err
} Prevention
- Size the context timeout to worst-case API latency
- Enable retries with exponential backoff
- Monitor API endpoint reachability
- Cache successful link resolutions to reduce API calls
When it happens
Trigger: Calling getLinks (via the resolver chain from an anonymous goroutine/caller) when the POST to ButtonListURL fails at transport level: ctx deadline exceeded after 20s, connection refused, TLS failure, or MaxRetries exhausted.
Common situations: The API endpoint being slower than the 20s context timeout under load; the API host blocked or DNS-failing; the site rate-limiting repeated getLinks calls; container without outbound access to the API host.
Understand the failure class
Background: "API request failed": what wrapped HTTP errors from external APIs mean and how to find the real cause — this error's family across 29 libraries.
Related errors
AI-assisted analysis of fish2018/pansou@beaa561337 (2026-09-07).
Data as JSON: /api/errors/f5ab3df267158d40.
Report an issue: GitHub.
Appendix: source
Thrown at plugin/susu/susu.go:355
return cachedLinks.([]model.Link), nil
}
form := url.Values{
"post_id": {postID},
"guest": {""},
}
ctx, cancel := context.WithTimeout(context.Background(), 20*time.Second)
defer cancel()
req, err := http.NewRequestWithContext(ctx, http.MethodPost, ButtonListURL, strings.NewReader(form.Encode()))
if err != nil {
return nil, fmt.Errorf("[susu] 创建按钮列表请求失败: %w", err)
}
setAPIHeaders(req, fmt.Sprintf("%s/%s.html", BaseURL, postID))
resp, err := p.doRequestWithRetry(client, req, MaxRetries)
if err != nil {
return nil, fmt.Errorf("[susu] 获取按钮列表失败: %w", err)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("[susu] 按钮列表请求返回状态码: %d", resp.StatusCode)
}
respBody, err := io.ReadAll(io.LimitReader(resp.Body, 2<<20))
if err != nil {
return nil, fmt.Errorf("[susu] 读取按钮列表失败: %w", err)
}
var groups []downloadGroup
if err := json.Unmarshal(respBody, &groups); err != nil {
return nil, fmt.Errorf("[susu] 解析按钮列表失败: %w", err)
}
totalButtons := 0
for _, group := range groups {View on GitHub (pinned to beaa561337)