fish2018/pansou · error

[ ] 首页返回状态码

Error message

[%s] 首页返回状态码: %d

What it means

Returned when the homepage request succeeds at the transport level but the server responds with a status code other than 200 OK. The plugin treats any non-200 homepage response as a hard failure and includes the numeric status in the message.

Solutions

  1. Log/read the status code in the message: 403/429 means blocking — change or rotate User-Agent headers in setHTMLHeaders
  2. Back off and retry later for 5xx codes (server-side problem)
  3. Reduce request frequency / add caching to avoid rate limits
  4. Check https://jsnoteclub.com/ manually in a browser to see if the site changed or moved
  5. Inspect response body for Cloudflare challenge pages and adjust headers accordingly

Example fix

// before
if resp.StatusCode != http.StatusOK {
    return "", fmt.Errorf("[%s] 首页返回状态码: %d", p.Name(), resp.StatusCode)
}
// after
if resp.StatusCode != http.StatusOK {
    return "", fmt.Errorf("[%s] 首页返回状态码: %d", p.Name(), resp.StatusCode) // 403/429 => adjust User-Agent; 5xx => retry with backoff
}
Defensive patterns

Strategy: try-catch

Try / catch

key, err := plugin.fetchDataKey(client)
if err != nil {
    var statusErr interface{ Error() string }
    if strings.Contains(err.Error(), "首页返回状态码") {
        // non-200 from upstream: handle 403/429 by rotating headers, 5xx by waiting
        return handleUpstreamStatus(err)
    }
    _ = statusErr
    return err
}

Prevention

When it happens

Trigger: GET https://jsnoteclub.com/ returns e.g. 403 (bot blocking/WAF), 429 (rate limit), 5xx (server error), or a 3xx that was not followed to a 200.

Common situations: Cloudflare or nginx blocking the plugin's User-Agent; server under maintenance returning 502/503; hitting the site too frequently and being rate limited; the site moved/redirected in a way the client's CheckRedirect policy rejects.

Related errors


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

Appendix: source

Thrown at plugin/jsnoteclub/jsnoteclub.go:241

func (p *JsNoteClubPlugin) fetchDataKey(client *http.Client) (string, error) {
	ctx, cancel := context.WithTimeout(context.Background(), requestTimeout)
	defer cancel()

	req, err := http.NewRequestWithContext(ctx, http.MethodGet, "https://jsnoteclub.com/", nil)
	if err != nil {
		return "", fmt.Errorf("[%s] 创建首页请求失败: %w", p.Name(), err)
	}
	setHTMLHeaders(req, "https://jsnoteclub.com/")

	resp, err := p.doRequestWithRetry(req, client, maxRequestRetries)
	if err != nil {
		return "", fmt.Errorf("[%s] 访问首页失败: %w", p.Name(), err)
	}
	defer resp.Body.Close()

	if resp.StatusCode != http.StatusOK {
		return "", fmt.Errorf("[%s] 首页返回状态码: %d", p.Name(), resp.StatusCode)
	}

	doc, err := goquery.NewDocumentFromReader(resp.Body)
	if err != nil {
		return "", fmt.Errorf("[%s] 解析首页失败: %w", p.Name(), err)
	}

	var htmlBuilder strings.Builder
	doc.Find("script").Each(func(_ int, s *goquery.Selection) {
		if html, err := goquery.OuterHtml(s); err == nil {
			htmlBuilder.WriteString(html)
		}
	})

	match := dataKeyRegex.FindStringSubmatch(htmlBuilder.String())
	if len(match) < 2 {
		return "", fmt.Errorf("[%s] 未能在首页找到 data-key", p.Name())
	}

View on GitHub (pinned to beaa561337)