yikart/AiToEarn · error · BadRequestException

检查视频发布状态失败: ${error.response?.data?.error?.message || error.

Error message

检查视频发布状态失败: ${error.response?.data?.error?.message || error.message}

What it means

checkPublishStatus POSTs the publish_id to TikTok's /v2/post/publish/status/fetch/ endpoint to poll whether an uploaded video finished processing/publishing. Any HTTP or network failure from that status endpoint is caught, logged, and re-thrown as BadRequestException('检查视频发布状态失败: ...') at tiktok.service.ts:482. Note: a valid response can still contain a FAILED status — this error only fires when the request itself fails.

Source

Thrown at project/aitoearn-electron/server/src/modules/plat/tiktok/tiktok.service.ts:482

  ): Promise<any> {
    try {
      const { data } = await firstValueFrom(
        this.httpService.post(
          `${this.apiBaseUrl}/v2/post/publish/status/fetch/`, 
          { publish_id: publishId },
          {
            headers: {
              'Content-Type': 'application/json',
              'Authorization': `Bearer ${accessToken}`
            }
          }
        )
      );

      return data.data;
    } catch (error) {
      this.logger.error('检查TikTok视频发布状态失败:', error.response?.data || error.message);
      throw new BadRequestException(`检查视频发布状态失败: ${error.response?.data?.error?.message || error.message}`);
    }
  }
  
  /**
   * 三步式完整上传并发布视频(新版API)
   * @param accessToken 访问令牌
   * @param userId 用户ID
   * @param accountId TikTok账号ID
   * @param videoBuffer 视频数据
   * @param videoInfo 视频信息
   * @param pollInterval 轮询状态的时间间隔(毫秒)。默认2秒。
   * @param maxRetries 最大重试次数。默认30次,大约60秒。
   * @returns 视频发布结果
   */
  async uploadAndPublishVideo(
    accessToken: string,
    userId: string,
    accountId: string,

View on GitHub (pinned to d3aa8bea5b)

Solutions

  1. Check the logged TikTok error body: for 401 refresh the access token; for invalid publish_id re-verify the upload actually succeeded and you are using the returned publish_id.
  2. Ensure apiBaseUrl matches the environment that issued the token and the publish_id (sandbox vs production).
  3. For 429 or transient errors, retry with exponential backoff instead of failing the whole poll loop.
  4. Increase the poll interval / reduce request frequency to stay within TikTok rate limits.

Example fix

// before
} catch (error) {
  this.logger.error('检查TikTok视频发布状态失败:', error.response?.data || error.message);
  throw new BadRequestException(`检查视频发布状态失败: ${error.response?.data?.error?.message || error.message}`);
}
// after
} catch (error) {
  this.logger.error('检查TikTok视频发布状态失败:', error.response?.data || error.message);
  if (error.response?.status === 429 || error.code === 'ECONNRESET' || error.code === 'ETIMEDOUT') {
    throw new HttpException('状态查询暂时失败,可重试', HttpStatus.SERVICE_UNAVAILABLE); // caller retries
  }
  throw new BadRequestException(`检查视频发布状态失败: ${error.response?.data?.error?.message || error.message}`);
}
Defensive patterns

Strategy: retry

Validate before calling

if (!publishId || typeof publishId !== 'string') {
  throw new Error('checkPublishStatus requires a non-empty publishId from a successful upload');
}

Type guard

function isPublishId(v) {
  return typeof v === 'string' && v.length > 0 && /^[A-Za-z0-9._-]+$/.test(v);
}

Try / catch

for (let attempt = 1; attempt <= 5; attempt++) {
  try {
    return await checkPublishStatus(accessToken, publishId);
  } catch (e) {
    const transient = e.message.includes('429') || e.message.includes('500') || /timeout|ECONNRESET/i.test(e.message);
    if (!transient || attempt === 5) throw e;
    await new Promise(r => setTimeout(r, Math.min(2 ** attempt * 1000, 15000)));
  }
}

Prevention

When it happens

Trigger: Any of: invalid/expired access token (401), invalid or unknown publish_id (400), polling too early/against the wrong environment (sandbox publish_ids not queryable in production), rate limiting (429), or transient network failure during polling.

Common situations: Polling with a publish_id from a failed upload, polling after the upload actually failed so TikTok rejects the id, mixing .cn/.ai or sandbox/production bases, token refresh racing with a long polling loop, and hitting TikTok rate limits with tight poll intervals.

Related errors


AI-assisted analysis of yikart/AiToEarn@d3aa8bea5b (2026-08-31). Data as JSON: /api/errors/5380d7c41da9c56b. Report an issue: GitHub.