fish2018/pansou · error

[ ] hsid= 链接请求返回状态码

Error message

[%s] hsid=%s链接请求返回状态码: %d

What it means

This error is thrown when the share-link HTTP response status code is anything other than 200. The plugin treats only HTTP 200 as success; upstream errors (4xx/5xx) like 403 anti-bot, 429 rate limit, or 502 upstream failure are reported here with the raw status code. Note the response body is not included, so the reason must be inferred.

Solutions

  1. Log the response body on non-200 to capture the upstream reason (read and truncate body before returning)
  2. Retry with backoff on 429/5xx statuses; treat 4xx as non-retryable
  3. Rotate User-Agent or route through a proxy if 403 persists
  4. Verify the fetch URL/path is still valid after API changes (404)
  5. Consider honoring Retry-After header on 429/503 responses.

Example fix

// before
if resp.StatusCode != 200 {
	return "", "", fmt.Errorf("[%s] hsid=%s链接请求返回状态码: %d", p.Name(), hsid, resp.StatusCode)
}
// after
if resp.StatusCode != 200 {
	snippet, _ := io.ReadAll(io.LimitReader(resp.Body, 200))
	return "", "", fmt.Errorf("[%s] hsid=%s链接请求返回状态码: %d (body=%s)", p.Name(), hsid, resp.StatusCode, string(snippet))
}
Defensive patterns

Strategy: retry

Validate before calling

// status can only be checked after the call; guard by retrying on retryable codes
if resp.StatusCode == 429 || resp.StatusCode >= 500 {
	// retry with backoff, honor Retry-After
}

Try / catch

if resp.StatusCode != http.StatusOK {
	body, _ := io.ReadAll(io.LimitReader(resp.Body, 512))
	return fmt.Errorf("unexpected status %d: %s", resp.StatusCode, body)
}

Prevention

When it happens

Trigger: fetchShareLink gets a response whose StatusCode != 200 after doRequestWithRetry succeeded at the transport level.

Common situations: haisou.cc anti-bot/WAF returns 403 for flagged UAs or IPs; rate limiting returns 429; upstream CDN returns 502/503 during outages; API path changed returning 404.

Related errors


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

Appendix: source

Thrown at plugin/haisou/haisou.go:409

	}

	// 设置请求头
	req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36")
	req.Header.Set("Accept", "application/json, text/plain, */*")
	req.Header.Set("Accept-Language", "zh-CN,zh;q=0.9,en;q=0.8")
	req.Header.Set("Connection", "keep-alive")
	req.Header.Set("Referer", "https://haisou.cc/")

	// 发送HTTP请求(带重试机制)
	resp, err := p.doRequestWithRetry(req, client)
	if err != nil {
		return "", "", fmt.Errorf("[%s] hsid=%s链接请求失败: %w", p.Name(), hsid, err)
	}
	defer resp.Body.Close()

	// 检查状态码
	if resp.StatusCode != 200 {
		return "", "", fmt.Errorf("[%s] hsid=%s链接请求返回状态码: %d", p.Name(), hsid, resp.StatusCode)
	}

	// 读取响应体
	body, err := io.ReadAll(resp.Body)
	if err != nil {
		return "", "", fmt.Errorf("[%s] hsid=%s读取响应失败: %w", p.Name(), hsid, err)
	}

	// 解析响应
	var apiResp FetchAPIResponse
	if err := json.Unmarshal(body, &apiResp); err != nil {
		return "", "", fmt.Errorf("[%s] hsid=%s链接JSON解析失败: %w", p.Name(), hsid, err)
	}

	// 检查API响应状态
	if apiResp.Code != 0 {
		return "", "", fmt.Errorf("[%s] hsid=%s链接API错误: %s", p.Name(), hsid, apiResp.Msg)
	}

View on GitHub (pinned to beaa561337)