fish2018/pansou · warning

[susu] 帖子 没有可用下载按钮

Error message

[susu] 帖子 %s 没有可用下载按钮

What it means

getLinks throws this when the button-list JSON decoded successfully but the total count of buttons across all groups is zero — the post exists (or the API pretends it does) yet exposes no download buttons. This is a domain-level empty-result guard, typically meaning the postID is wrong, the post was deleted, or it never had download content.

Solutions

  1. Verify the postID by opening BaseURL/<postID>.html in a browser and confirming download buttons render.
  2. Check that the JSON groups actually map to the current site structure (a field rename can silently zero out Button).
  3. Handle gracefully upstream: treat as 'no downloadable content' rather than a hard failure when appropriate.
  4. Refresh cached search results — the post may have been deleted since the search index cached it.

Example fix

null
Defensive patterns

Strategy: fallback

Validate before calling

// resolve links only for postIDs known to have content
if postID == "" || !postIDPattern.MatchString(postID) {
    // skip getLinks for malformed IDs
}

Try / catch

links, err := p.getLinks(postID)
if err != nil && strings.Contains(err.Error(), "没有可用下载按钮") {
    // treat as 'no downloadable content', not a hard error
    return model.LinkResults{}, nil
}

Prevention

When it happens

Trigger: After json.Unmarshal into []downloadGroup, summing len(group.Button) over all groups yields 0 — empty array, groups with empty Button slices, or a structurally valid but contentless response (e.g. API returning [] for unknown postIDs).

Common situations: Passing a stale or mistyped postID; the post's downloads were removed or the post deleted; scraping a post type that uses a different download mechanism; API returning empty results for region/language variants.

Understand the failure class

Background: EmptyResultError / "no results found": when an API or scraper succeeds but returns zero rows — this error's family across 9 libraries.

Related errors


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

Appendix: source

Thrown at plugin/susu/susu.go:377

		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 {
		totalButtons += len(group.Button)
	}
	if totalButtons == 0 {
		return nil, fmt.Errorf("[susu] 帖子 %s 没有可用下载按钮", postID)
	}

	linkChan := make(chan model.Link, totalButtons)
	var wgLinks sync.WaitGroup
	semaphore := make(chan struct{}, MaxConcurrency)

	for groupIndex, group := range groups {
		for buttonIndex := range group.Button {
			wgLinks.Add(1)
			go func(index, i int) {
				defer wgLinks.Done()
				semaphore <- struct{}{}
				defer func() { <-semaphore }()

				link, err := p.getButtonDetail(client, postID, index, i)
				if err == nil && link.URL != "" {
					linkChan <- link
				}

View on GitHub (pinned to beaa561337)