fish2018/pansou · error

获取预登录会话失败: HTTP

Error message

获取预登录会话失败: HTTP %d

What it means

doLogin first issues a GET to the panlian base URL to establish a pre-login session/cookie jar. If that request returns a non-200 status code, this error is thrown with the actual HTTP status embedded.

Solutions

  1. Check whether the panlian site is reachable in a browser / currently under maintenance
  2. Retry with backoff; 5xx are usually transient
  3. Send browser-like headers (User-Agent, Accept) on the pre-login GET to avoid WAF blocks
  4. Check proxy/firewall settings if a corporate proxy is in the path

Example fix

// before
resp, err := client.Get(DefaultBaseURL)
if resp.StatusCode != http.StatusOK {
    return "", nil, fmt.Errorf("获取预登录会话失败: HTTP %d", resp.StatusCode)
}
// after
req, _ := http.NewRequest(http.MethodGet, DefaultBaseURL, nil)
req.Header.Set("User-Agent", userAgent)
req.Header.Set("Accept", "text/html")
resp, err := client.Do(req)
if err != nil { return "", nil, err }
if resp.StatusCode != http.StatusOK {
    return "", nil, fmt.Errorf("获取预登录会话失败: HTTP %d", resp.StatusCode)
}
Defensive patterns

Strategy: retry

Validate before calling

u, err := url.Parse(DefaultBaseURL)
if err != nil || u.Scheme == "" || u.Host == "" {
    return errors.New("invalid panlian base URL")
}

Try / catch

var resp *http.Response
var err error
for attempt := 0; attempt < 3; attempt++ {
    resp, err = client.Get(DefaultBaseURL)
    if err == nil && resp.StatusCode == 200 { break }
    time.Sleep(time.Duration(attempt+1) * time.Second)
}

Prevention

When it happens

Trigger: The initial GET to DefaultBaseURL returns e.g. 403 (WAF/anti-bot), 502/503 (backend down), 30x not followed, or 429 rate limit.

Common situations: Panlian site temporarily down or under maintenance; request blocked by anti-bot protection because of missing/suspicious headers; corporate proxy returning errors.

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/58f5ea7f05737ed1. Report an issue: GitHub.

Appendix: source

Thrown at plugin/panlian/panlian.go:1088

	// 站点登录只认预先由公开接口建立的 PHPSESSID。
	ctx, cancel := context.WithTimeout(context.Background(), RequestTimeout)
	req, err := http.NewRequestWithContext(ctx, http.MethodGet, DefaultBaseURL+"/api/get_types.php", nil)
	if err != nil {
		cancel()
		return "", nil, err
	}
	p.setPanlianHeaders(req, "", DefaultBaseURL+"/all-videos.php")
	resp, err := client.Do(req)
	if err != nil {
		cancel()
		return "", nil, err
	}
	io.Copy(io.Discard, resp.Body)
	resp.Body.Close()
	cancel()
	if resp.StatusCode != http.StatusOK {
		return "", nil, fmt.Errorf("获取预登录会话失败: HTTP %d", resp.StatusCode)
	}
	baseURL, _ := url.Parse(DefaultBaseURL)
	preCookie := cookiesToString(jar.Cookies(baseURL))

	form := url.Values{}
	form.Set("username", username)
	form.Set("password", password)
	if remember {
		form.Set("remember", "on")
	}

	ctx, cancel = context.WithTimeout(context.Background(), RequestTimeout)
	req, err = http.NewRequestWithContext(ctx, http.MethodPost, DefaultBaseURL+"/api/login.php", strings.NewReader(form.Encode()))
	if err != nil {
		cancel()
		return "", nil, err
	}
	p.setPanlianHeaders(req, preCookie, DefaultBaseURL+"/pages/login.php")

View on GitHub (pinned to beaa561337)