iawia002/lux · error

string(playAuth.Error)

Error message

string(playAuth.Error)

What it means

The second geekbang call, serv/v3/source_auth/video_play_auth, returned code < 0 and its raw error JSON (a json.RawMessage) is surfaced verbatim. The article lookup succeeded but the play-license step was rejected — expired auth, video_id mismatch, or server-side throttling.

Source

Thrown at extractors/geekbang/geekbang.go:130

	if data.Data.VideoID == "" && !data.Data.ColumnHadSub {
		return nil, errors.New("请先购买课程,或使用Cookie登录。")
	}

	// Get video license token information
	params = strings.NewReader("{\"source_type\":1,\"aid\":" + matches[2] + ",\"video_id\":\"" + data.Data.VideoID + "\"}")
	res, err = request.Request(http.MethodPost, "https://time.geekbang.org/serv/v3/source_auth/video_play_auth", params, heanders)
	if err != nil {
		return nil, errors.WithStack(err)
	}
	defer res.Body.Close() // nolint

	var playAuth videoPlayAuth
	if err = json.NewDecoder(res.Body).Decode(&playAuth); err != nil {
		return nil, errors.WithStack(err)
	}

	if playAuth.Code < 0 {
		return nil, errors.New(string(playAuth.Error))
	}

	// Get video playback information
	heanders = map[string]string{"Accept-Encoding": ""}
	res, err = request.Request(http.MethodGet, "http://ali.mantv.top/play/info?playAuth="+playAuth.Data.PlayAuth, nil, heanders)
	if err != nil {
		return nil, errors.WithStack(err)
	}
	defer res.Body.Close() // nolint

	var playInfo playInfo
	if err = json.NewDecoder(res.Body).Decode(&playInfo); err != nil {
		return nil, errors.WithStack(err)
	}

	title := data.Data.Title

	streams := make(map[string]*extractors.Stream, len(playInfo.PlayInfoList.PlayInfo))

View on GitHub (pinned to dd00f6d258)

Solutions

  1. Retry the single failing URL — play-auth rejections are often transient.
  2. Re-export a fresh cookie and retry the batch.
  3. Log the raw playAuth JSON body to see the server's exact reason.

Example fix

// before
if playAuth.Code < 0 {
	return nil, errors.New(string(playAuth.Error))
}
// after — include the server code and raw reason
if playAuth.Code < 0 {
	return nil, fmt.Errorf("video_play_auth failed (code %d): %s", playAuth.Code, string(playAuth.Error))
}
Defensive patterns

Strategy: retry

Try / catch

Retry the failing URL once after a short delay and, if it persists, with a freshly exported cookie; the play-auth step is stateful and often transiently rejected. Surface the raw playAuth.Error JSON when giving up.

Prevention

When it happens

Trigger: A cookie valid for article info but rejected for play auth; batch runs where the license request goes stale; a changed v3 API contract; rate limiting after many sequential downloads.

Common situations: Long queues of geekbang URLs; old exported cookies; API behavior changes after maintenance windows.

Related errors


AI-assisted analysis of iawia002/lux@dd00f6d258 (2026-08-15). Data as JSON: /api/errors/420820890e40a728. Report an issue: GitHub.