fish2018/pansou · error

请求失败,状态: , 详情

Error message

请求失败,状态: %s, 详情: %s

What it means

The homepage request returned a non-200 status code, and the response body was successfully read, so the function reports the full HTTP status line (e.g. "404 Not Found") together with the body contents. This is the primary diagnostic error for server-side rejections of the homepage request: 403/429 from anti-bot protection, 404/410 if the site restructured, 5xx if the origin is unhealthy.

Solutions

  1. Read the 详情 body: a Cloudflare challenge/HTML error page there tells you the request is being blocked — switch to a residential IP or solve the challenge.
  2. If 429, back off and retry with a delay; add client-side rate limiting before calling discoverActionIDs.
  3. If 404/410, update the plugin's configured base URL — the site likely restructured.
  4. If 5xx, wait and retry; it is a server-side problem, not a client bug.
  5. Send browser-like headers (already partially done) and verify the User-Agent isn't stale versus the WAF's expectations.
Defensive patterns

Strategy: try-catch

Type guard

func isRetryableStatus(code int) bool {
    switch code {
    case http.StatusTooManyRequests,
        http.StatusBadGateway,
        http.StatusServiceUnavailable,
        http.StatusGatewayTimeout:
        return true
    }
    return code >= 500
}

Try / catch

err := discoverActionIDs(ctx)
if err != nil {
    if strings.Contains(err.Error(), "状态: 429") || strings.Contains(err.Error(), "状态: 5") {
        time.Sleep(backoff)
        return discoverActionIDs(ctx)
    }
    if strings.Contains(err.Error(), "状态: 404") {
        return fmt.Errorf("site layout changed; update base URL")
    }
    return err
}

Prevention

When it happens

Trigger: client.Do succeeded in findPotentialActionIDs but resp.StatusCode != http.StatusOK (e.g. 403 from Cloudflare, 429 rate limit, 502/503 from origin) and io.ReadAll(resp.Body) succeeded.

Common situations: Cloudflare/WAF challenge page returned for datacenter IPs; rate limiting after repeated calls to discoverActionIDs; site deployed a new version changing routes so old homepage paths 404; origin server temporarily down returning 5xx.

Understand the failure class

Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.

Related errors


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

Appendix: source

Thrown at plugin/panyq/panyq.go:674

	req.Header.Set("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36")
	
	// 发送请求
	resp, err := client.Do(req)
	if err != nil {
		return nil, fmt.Errorf("请求网站首页失败: %w", err)
	}
	defer resp.Body.Close()
	
	// 检查状态码
	if resp.StatusCode != http.StatusOK {
		// 读取响应体以获取服务器返回的具体错误信息
		bodyBytes, err := io.ReadAll(resp.Body)
		if err != nil {
			// 如果连响应体都读取失败,则返回状态码错误并附上读取错误
			return nil, fmt.Errorf("请求失败,状态码: %d,且读取响应体错误: %v", resp.StatusCode, err)
		}
		// 将更详细的状态信息 (如 "404 Not Found") 和响应体内容一起作为错误返回
		return nil, fmt.Errorf("请求失败,状态: %s, 详情: %s", resp.Status, string(bodyBytes))
	}

	body, err := io.ReadAll(resp.Body)
	if err != nil {
		return nil, fmt.Errorf("读取响应失败: %w", err)
	}
	
	// 提取JS文件路径
	jsRegex := regexp.MustCompile(`<script src="(/_next/static/[^"]+\.js)"`)
	matches := jsRegex.FindAllStringSubmatch(string(body), -1)
	
	if len(matches) == 0 {
		return nil, fmt.Errorf("未找到JS文件")
	}
	
	// 收集所有潜在的Action ID
	idSet := make(map[string]struct{})
	idRegex := regexp.MustCompile(`["\']([a-f0-9]{40})["\']{1}`)

View on GitHub (pinned to beaa561337)