fish2018/pansou · error

下载链接请求失败

Error message

下载链接请求失败: %w

What it means

getDownloadLinks in the cyg plugin wraps any transport-level failure of the HTTP request used to fetch download links with the prefix "下载链接请求失败". It means p.doRequestWithRetry exhausted its attempts (network error, DNS failure, timeout) or returned a non-nil error. The original cause is preserved via %w so errors.Is/As on the wrapped error works.

Solutions

  1. Inspect the wrapped cause (errors.Unwrap / %v of the returned error) to see whether it is a timeout, DNS, or TLS failure.
  2. Verify network connectivity and that https://www.cygtu.com (or the configured host) is reachable, e.g. with curl.
  3. Increase the HTTP client timeout or retry count used by doRequestWithRetry.
  4. Check whether the target site now requires headers/cookies the plugin does not send (site layout/anti-bot change) and update setRequestHeaders.

Example fix

// before
links, err := p.getDownloadLinks(id)
if err != nil {
    return err // opaque Chinese-wrapped error
}
// after
links, err := p.getDownloadLinks(id)
if err != nil {
    var ne net.Error
    if errors.As(err, &ne) && ne.Timeout() {
        return fmt.Errorf("download links timed out, increase client timeout: %w", err)
    }
    return err
}
Defensive patterns

Strategy: try-catch

Validate before calling

url, _ := url.Parse(baseURL)
if url == nil || url.Host == "" {
    return fmt.Errorf("unreachable base url")
}

Try / catch

links, err := p.getDownloadLinks(id)
if err != nil {
    var ne net.Error
    if errors.As(err, &ne) && ne.Timeout() {
        // retry with longer timeout
    }
    return nil, fmt.Errorf("download links unavailable: %w", err)
}

Prevention

When it happens

Trigger: Calling the plugin's download-link lookup when the GET to the cyg API fails at the transport layer in doRequestWithRetry: network unreachable, TLS error, request context timeout, or all retry attempts exhausted with a non-HTTP error.

Common situations: Offline or flaky network, the site blocking the client (TLS reset / anti-bot), DNS resolution failure, or a too-short HTTP client timeout while fetching download links.

Understand the failure class

Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.

Related errors


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

Appendix: source

Thrown at plugin/cyg/cyg.go:240

	downloadURL := fmt.Sprintf(cygBaseURL+"/wp-json/acg-studio/v1/download?id=%d", postID)

	// 创建带超时的上下文
	ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
	defer cancel()

	// 创建请求对象
	req, err := http.NewRequestWithContext(ctx, "GET", downloadURL, nil)
	if err != nil {
		return nil, fmt.Errorf("创建下载链接请求失败: %w", err)
	}

	// 设置请求头
	p.setRequestHeaders(req)

	// 发送请求
	resp, err := p.doRequestWithRetry(req, client)
	if err != nil {
		return nil, fmt.Errorf("下载链接请求失败: %w", err)
	}
	defer resp.Body.Close()

	// 检查状态码
	if resp.StatusCode != 200 {
		return nil, fmt.Errorf("下载链接请求状态码: %d", resp.StatusCode)
	}

	// 解析响应
	body, err := io.ReadAll(resp.Body)
	if err != nil {
		return nil, fmt.Errorf("读取下载链接响应失败: %w", err)
	}

	var downloadData []CygDownload
	if err := json.Unmarshal(body, &downloadData); err != nil {
		return nil, fmt.Errorf("下载链接JSON解析失败: %w", err)
	}

View on GitHub (pinned to beaa561337)