fish2018/pansou · error

[ ] hsid= 链接API错误

Error message

[%s] hsid=%s链接API错误: %s

What it means

This error is thrown when the share-link API responded with valid JSON but a non-zero Code field, i.e. a business-level rejection from the haisou upstream. The API's own message (apiResp.Msg) is included — typical upstream reasons are invalid/expired hsid, missing quota, or authentication issues with the upstream aggregator.

Solutions

  1. Read apiResp.Msg in the error and act on the upstream reason
  2. Verify the hsid exists/is still valid before conversion (or handle revocation gracefully)
  3. Check upstream API key/token validity and renewal
  4. Retry on transient upstream codes; fail fast on permanent ones (invalid hsid)

Example fix

// before
if apiResp.Code != 0 {
	return "", "", fmt.Errorf("[%s] hsid=%s链接API错误: %s", p.Name(), hsid, apiResp.Msg)
}
// after
if apiResp.Code != 0 {
	if apiResp.Code == codeShareRevoked {
		return "", "", fmt.Errorf("[%s] hsid=%s分享已失效(上游code=%d): %s", p.Name(), hsid, apiResp.Code, apiResp.Msg) // permanent, do not retry
	}
	return "", "", fmt.Errorf("[%s] hsid=%s链接API错误: code=%d msg=%s", p.Name(), hsid, apiResp.Code, apiResp.Msg)
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Code is only known post-response; defend by classifying codes
switch {
case apiResp.Code == 0:
	// proceed
case isPermanentCode(apiResp.Code):
	// do not retry
default:
	// retry with backoff
}

Type guard

func upstreamAccepted(resp FetchAPIResponse) bool { return resp.Code == 0 }

Try / catch

if apiResp.Code != 0 {
	return fmt.Errorf("share link API error: code=%d msg=%s", apiResp.Code, apiResp.Msg)
}

Prevention

When it happens

Trigger: fetchShareLink receives a successfully-parsed FetchAPIResponse whose Code != 0.

Common situations: hsid is stale/deleted upstream (share already revoked); upstream account quota exhausted; API key/token missing or expired; upstream service temporarily rejecting requests.

Related errors


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

Appendix: source

Thrown at plugin/haisou/haisou.go:426

	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)
	}

	// 根据平台类型构建完整的分享链接
	shareURL := buildShareURL(platform, apiResp.Data.ShareCode)
	if shareURL == "" {
		return "", "", fmt.Errorf("[%s] hsid=%s不支持的网盘平台: %s", p.Name(), hsid, platform)
	}

	// 获取密码
	password := ""
	if apiResp.Data.SharePwd != nil {
		password = *apiResp.Data.SharePwd
	}

	if DebugLog {
		fmt.Printf("[%s] hsid=%s成功获取链接: %s password=%s\n", p.Name(), hsid, shareURL, password)
	}

View on GitHub (pinned to beaa561337)