fish2018/pansou · error

[susu] 按钮返回无效链接

Error message

[susu] 按钮返回无效链接

What it means

Post-decode guard: the JWT decoded to a string that is not a usable link — url.Parse failed, or the scheme is not http/https. The upstream token is structurally valid but carries a garbage/relative payload.

Solutions

  1. Log the decoded string to see the actual payload
  2. Skip this result as permanently invalid
  3. Consider prepending a base host if payloads are relative paths
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at plugin/susu/susu.go:487 when the library encounters an invalid state.

Common situations: See trigger scenarios.


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

Appendix: source

Thrown at plugin/susu/susu.go:487

	var buttonDetail buttonDetailResponse
	if err := json.Unmarshal(respBody, &buttonDetail); err != nil {
		return model.Link{}, fmt.Errorf("[susu] 解析按钮详情失败: %w", err)
	}

	// 如果URL为空
	if buttonDetail.Button.URL == "" {
		return model.Link{}, fmt.Errorf("[susu] 按钮URL为空")
	}

	// 解析JWT token获取真实链接
	realURL, err := p.decodeJWTURL(buttonDetail.Button.URL)
	if err != nil {
		return model.Link{}, fmt.Errorf("[susu] 解析JWT失败: %w", err)
	}
	realURL = strings.TrimSpace(realURL)
	parsedURL, err := url.Parse(realURL)
	if err != nil || (parsedURL.Scheme != "http" && parsedURL.Scheme != "https") || parsedURL.Host == "" {
		return model.Link{}, fmt.Errorf("[susu] 按钮返回无效链接")
	}

	// 创建链接
	link := model.Link{
		URL:      realURL,
		Type:     p.determineLinkType(realURL, buttonDetail.Button.Name),
		Password: extractPassword(realURL, buttonDetail.Button.Attr.TQ),
	}

	// 缓存结果
	buttonDetailCache.Store(cacheKey, link)

	return link, nil
}

// decodeJWTURL 解析JWT token获取真实链接
func (p *SusuAsyncPlugin) decodeJWTURL(jwtToken string) (string, error) {
	if strings.HasPrefix(jwtToken, "http://") || strings.HasPrefix(jwtToken, "https://") {

View on GitHub (pinned to beaa561337)