yikart/AiToEarn · warning · BadRequestException

视频发布状态检查超时,请稍后在TikTok应用中查看发布状态

Error message

视频发布状态检查超时,请稍后在TikTok应用中查看发布状态

What it means

Thrown by uploadAndPublishVideo (tiktok.service.ts:590) when the polling loop exhausts maxRetries (default 30 × 2s ≈ 60s) without the status ever reaching SUCCESS/PUBLISHED or FAILED/ERROR. TikTok is still processing the video, or the status endpoint returns an unrecognized status value so the loop never matches.

Source

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

            updateTime: new Date()
          });
          
          throw new BadRequestException(`视频发布失败: ${statusResult.error_message || '未知错误'}`);
        }
        
        // 等待指定时间后再次查询
        await new Promise(resolve => setTimeout(resolve, pollInterval));
      }
      
      if (!finalStatus) {
        // 超时仍未完成
        await this.pubRecordModel.findByIdAndUpdate(pubRecord._id, {
          status: PubStatus.FAIL,
          failReason: '检查视频发布状态超时',
          updateTime: new Date()
        });
        
        throw new BadRequestException('视频发布状态检查超时,请稍后在TikTok应用中查看发布状态');
      }
      
      // 更新发布记录为成功状态
      const videoId = finalStatus.video_id || finalStatus.id || publish_id;
      await this.pubRecordModel.findByIdAndUpdate(pubRecord._id, {
        status: PubStatus.RELEASED,
        resourceId: videoId,
        updateTime: new Date()
      });
      
      return {
        ...finalStatus,
        resourceId: videoId,
        publish_id,
      };
    } catch (error) {
      this.logger.error('三步式视频上传发布失败:', error.response?.data || error.message);
      throw new BadRequestException(`视频上传发布失败: ${error.response?.data?.error?.message || error.message}`);

View on GitHub (pinned to d3aa8bea5b)

Solutions

  1. Increase maxRetries and/or pollInterval when calling uploadAndPublishVideo for large videos.
  2. Log every statusResult.status value and add the unrecognized values to the terminal-status comparison.
  3. Treat status as succeeded-if-processed by checking statusResult.data?.status when the payload is nested.
  4. Make the failure non-fatal: since the video may still publish, return the publish_id and let the caller verify later instead of throwing.
  5. Implement exponential backoff to cover longer processing windows without more API calls.

Example fix

// before
if (statusResult.status === 'SUCCESS' || statusResult.status === 'PUBLISHED') {
// after
const ok = ['SUCCESS', 'PUBLISHED', 'SENDING', 'FINISH'];
if (ok.includes(statusResult?.status) || statusResult?.data?.status === 'SUCCESS') {
Defensive patterns

Strategy: retry

Validate before calling

null

Type guard

function isTerminalStatus(s: any): boolean {
  return ['SUCCESS', 'PUBLISHED', 'FAILED', 'ERROR'].includes(String(s?.status ?? '').toUpperCase());
}

Try / catch

try {
  await tiktokService.uploadAndPublishVideo(token, userId, accountId, buffer, info, 3000, 60);
} catch (e) {
  if (e.message.includes('状态检查超时')) {
    // publish may still complete: schedule a background job to re-check publish_id later
    await queueStatusRecheck(accountId, publishId);
  } else throw e;
}

Prevention

When it happens

Trigger: 30 consecutive status polls return a non-terminal status (e.g. 'PROCESSING', 'PUBLISHING', or a different casing/wording the code doesn't recognize), so finalStatus remains null after the while loop.

Common situations: Large videos taking longer than ~60s to process; TikTok changing the status enum values (e.g. returning 'SENDING' or 'FINISH'); the status check succeeding but with status undefined due to response-shape drift; heavy TikTok-side processing queues.

Related errors


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