fish2018/pansou · error

[ ] 详情接口返回异常: success= code=

Error message

[%s] 详情接口返回异常: success=%v code=%d

What it means

The getVideoDetail JSON parsed but the envelope check failed: resp.Success was false or resp.Code was not 200, so fetchDetail aborts reporting both values. The upstream API explicitly signaled an error for this detail request.

Solutions

  1. Include the API's message field in the log to learn the exact upstream reason
  2. Validate the doubID exists (via search results) before fetching details
  3. Verify lingjiIdentity and other params against the current API docs
  4. Add backoff for code values indicating throttling
  5. Update the plugin if the API changed status-code semantics
Defensive patterns

Strategy: try-catch

Validate before calling

// Only query ids that came from a successful search response
if doubID <= 0 || !idFromSearchResults(doubID) {
    return lingjiVideoItem{}, fmt.Errorf("跳过未知详情ID: %d", doubID)
}

Try / catch

item, err := fetchDetail(doubID)
var apiErr *LingjiAPIError
if errors.As(err, &apiErr) {
    switch {
    case apiErr.Code == http.StatusNotFound:
        return emptyItem, nil // record genuinely not found upstream
    case isThrottleCode(apiErr.Code):
        time.Sleep(backoff)
        return fetchDetail(doubID)
    default:
        return emptyItem, err
    }
}

Prevention

When it happens

Trigger: Valid JSON from getVideoDetail whose success=false or code!=200 — typically id not found in the API's database, invalid/missing identity parameter, or upstream-side rate limiting/authorization failure.

Common situations: Requested douban id doesn't exist upstream (record-not-found from the API); lingjiIdentity stale after API update; API throttles bursts of detail lookups during scraping; account/token requirements introduced by an API version change.

Related errors


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

Appendix: source

Thrown at plugin/lingjisp/lingjisp.go:229

func (p *LingjiPlugin) fetchDetail(client *http.Client, doubID int) (lingjiVideoItem, error) {
	params := url.Values{}
	params.Set("app_id", lingjiAppID)
	params.Set("identity", lingjiIdentity)
	params.Set("id", fmt.Sprintf("%d", doubID))

	apiURL := lingjiAPIBase + "getVideoDetail?" + params.Encode()
	body, err := doLingjiGET(client, apiURL, lingjiDetailTimeout)
	if err != nil {
		return lingjiVideoItem{}, fmt.Errorf("[%s] 详情请求失败: %w", p.Name(), err)
	}

	var resp lingjiDetailResponse
	if err := json.Unmarshal(body, &resp); err != nil {
		return lingjiVideoItem{}, fmt.Errorf("[%s] 解析详情响应失败: %w", p.Name(), err)
	}
	if !resp.Success || resp.Code != http.StatusOK {
		return lingjiVideoItem{}, fmt.Errorf("[%s] 详情接口返回异常: success=%v code=%d", p.Name(), resp.Success, resp.Code)
	}
	return resp.Data, nil
}

func doLingjiGET(client *http.Client, requestURL string, timeout time.Duration) ([]byte, error) {
	var lastErr error

	for attempt := 0; attempt < lingjiMaxRetries; attempt++ {
		ctx, cancel := context.WithTimeout(context.Background(), timeout)
		req, err := http.NewRequestWithContext(ctx, http.MethodGet, requestURL, nil)
		if err != nil {
			cancel()
			return nil, err
		}

		req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 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")

View on GitHub (pinned to beaa561337)