fish2018/pansou · error

详情接口返回 code=403,登录状态可能已失效

Error message

详情接口返回 code=403,登录状态可能已失效

What it means

fetchDetail parses the JSON DetailData and throws this error when the payload's own code field equals 403 — the site returned well-formed JSON but reports that the login state is invalid. Unlike the HTTP-level 403s, this is an application-layer signal that the session cookie no longer authenticates the account.

Solutions

  1. Re-run the plugin's login flow to refresh the session, then retry.
  2. Persist and reload cookies so restarts don't reuse dead sessions.
  3. If re-login keeps failing, verify the account is valid and not rate-limited/banned in a browser.
  4. Add automatic session-refresh on this error in the calling code.

Example fix

// before
detail, err := plugin.fetchDetail(id, typ, scraper) // code=403
// after
if err != nil && strings.Contains(err.Error(), "code=403") {
    if rerr := plugin.Relogin(ctx); rerr != nil { return rerr }
    detail, err = plugin.fetchDetail(id, typ, scraper)
}
Defensive patterns

Strategy: try-catch

Validate before calling

// check session health via a lightweight endpoint before batch runs
if !plugin.SessionHealthy(ctx) { plugin.Relogin(ctx) }

Type guard

func isSessionExpired(err error) bool { return err != nil && strings.Contains(err.Error(), "code=403") }

Try / catch

detail, err := plugin.fetchDetail(id, typ, scraper)
if isSessionExpired(err) {
    if rerr := plugin.Relogin(ctx); rerr != nil { return rerr }
    detail, err = plugin.fetchDetail(id, typ, scraper)
}

Prevention

When it happens

Trigger: Calling fetchDetail when the site returns HTTP 200 JSON whose code field is 403: session expired server-side, cookie revoked by another login, or the account was logged out / banned.

Common situations: Long-lived deployments whose cookie TTL elapsed; account logged in elsewhere invalidating the session; site rotating session secrets; using an account that requires re-verification.

Related errors


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

Appendix: source

Thrown at plugin/gying/gying.go:2758

			preview := string(body)
			if len(preview) > 200 {
				preview = preview[:200] + "..."
			}
			fmt.Printf("[Gying]     响应内容: %s\n", preview)
		}
		return nil, err
	}

	if DebugLog {
		fmt.Printf("[Gying]     详情Code: %d, 网盘链接数: %d\n", detail.Code, len(detail.Panlist.URL))
	}

	// 检查JSON响应中的code字段(关键!)
	if detail.Code == 403 {
		if DebugLog {
			fmt.Printf("[Gying]     ❌ 详情接口返回Code=403 - 登录状态可能已失效\n")
		}
		return nil, fmt.Errorf("详情接口返回 code=403,登录状态可能已失效")
	}

	return &detail, nil
}

// buildResult 构建SearchResult
func (p *GyingPlugin) buildResult(detail *DetailData, searchData *SearchData, index int) model.SearchResult {
	if index >= len(searchData.L.Title) {
		return model.SearchResult{}
	}

	title := searchData.L.Title[index]
	resourceType := searchData.L.D[index]
	resourceID := searchData.L.I[index]

	// 获取年份并拼接到标题后面
	var year int
	if index < len(searchData.L.Year) && searchData.L.Year[index] > 0 {

View on GitHub (pinned to beaa561337)