fish2018/pansou · error

[susu] 读取按钮详情失败

Error message

[susu] 读取按钮详情失败: %w

What it means

Reading the (2MB-capped) susu button-detail response body failed mid-stream after a 200: connection reset, read timeout, or truncation by an intermediary. The status check already passed; only the body transfer broke.

Solutions

  1. Retry the button-detail request
  2. Keep the LimitReader cap to avoid unbounded reads
  3. Check for proxies truncating responses
Defensive patterns

Strategy: retry

When it happens

Trigger: Thrown at plugin/susu/susu.go:465 when the library encounters an invalid state.

Common situations: See trigger scenarios.


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

Appendix: source

Thrown at plugin/susu/susu.go:465

	if err != nil {
		return model.Link{}, fmt.Errorf("[susu] 创建按钮详情请求失败: %w", err)
	}
	setAPIHeaders(req, fmt.Sprintf("%s/download?post_id=%s&index=%d&i=%d", BaseURL, postID, index, i))

	// 发送请求(带重试)
	resp, err := p.doRequestWithRetry(client, req, MaxRetries)
	if err != nil {
		return model.Link{}, fmt.Errorf("[susu] 获取按钮详情失败: %w", err)
	}
	defer resp.Body.Close()
	if resp.StatusCode != http.StatusOK {
		return model.Link{}, fmt.Errorf("[susu] 按钮详情请求返回状态码: %d", resp.StatusCode)
	}

	// 读取响应体
	respBody, err := io.ReadAll(io.LimitReader(resp.Body, 2<<20))
	if err != nil {
		return model.Link{}, fmt.Errorf("[susu] 读取按钮详情失败: %w", err)
	}

	// 解析响应
	var buttonDetail buttonDetailResponse
	if err := json.Unmarshal(respBody, &buttonDetail); err != nil {
		return model.Link{}, fmt.Errorf("[susu] 解析按钮详情失败: %w", err)
	}

	// 如果URL为空
	if buttonDetail.Button.URL == "" {
		return model.Link{}, fmt.Errorf("[susu] 按钮URL为空")
	}

	// 解析JWT token获取真实链接
	realURL, err := p.decodeJWTURL(buttonDetail.Button.URL)
	if err != nil {
		return model.Link{}, fmt.Errorf("[susu] 解析JWT失败: %w", err)
	}

View on GitHub (pinned to beaa561337)