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
- 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.
- Ensure apiBaseUrl matches the environment that issued the token and the publish_id (sandbox vs production).
- For 429 or transient errors, retry with exponential backoff instead of failing the whole poll loop.
- 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
- Only poll with a publish_id returned from a verified-successful upload.
- Use a poll interval of 2s or more and cap total retries to avoid rate limits.
- Keep the status-check base URL in the same environment (sandbox/prod, cn/ai) as the upload.
- Refresh the access token for long-running poll loops before it expires.
- Treat repeated 'invalid publish_id' errors as an upload failure, not a polling issue.
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
- 分片上传视频失败: ${error.response?.data?.error?.message || error.me
- 直接上传视频失败: ${error.response?.data?.error?.message || error.me
- 交换授权码失败: ${error.response?.data?.error_description || error.
- ${err.response?.data?.error_description || '刷新令牌失败'}
- 15070
AI-assisted analysis of yikart/AiToEarn@d3aa8bea5b (2026-08-31).
Data as JSON: /api/errors/5380d7c41da9c56b.
Report an issue: GitHub.