yikart/AiToEarn · error · BadRequestException
分片上传视频失败: ${error.response?.data?.error?.message || error.me
Error message
分片上传视频失败: ${error.response?.data?.error?.message || error.message} What it means
This is the catch-all wrapper for uploadVideoChunked: any failure during chunked upload of a TikTok video (network error, HTTP 4xx/5xx from the upload_url, timeout, or even the internal 'missing publish_id' BadRequestException from line 316) is logged and re-thrown as BadRequestException('分片上传视频失败: ...') at tiktok.service.ts:367. The message embeds error.response.data.error.message for Axios errors, else error.message.
Source
Thrown at project/aitoearn-electron/server/src/modules/plat/tiktok/tiktok.service.ts:367
}
})
);
uploadResponses.push(data);
}
// 使用最后一个分片的响应作为最终响应
const finalResponse = uploadResponses[totalChunkCount - 1];
return {
...finalResponse.data,
publish_id,
video_id: finalResponse.data?.video_id || finalResponse.data?.id,
init_data: initData, // 返回初始化数据,可能在发布时需要
};
} catch (error) {
this.logger.error('分片上传TikTok视频失败:', error.response?.data || error.message);
throw new BadRequestException(`分片上传视频失败: ${error.response?.data?.error?.message || error.message}`);
}
}
/**
* 方式2:直接上传视频(PUT方式)
* @param accessToken 访问令牌
* @param videoBuffer 视频文件缓冲区
* @param initData 初始化返回的数据,包含 publish_id 和 upload_url
* @returns 上传结果
*/
async directUploadVideo(
accessToken: string,
videoBuffer: Buffer,
initData: any
): Promise<any> {
try {
const { publish_id, upload_url } = initData;
View on GitHub (pinned to d3aa8bea5b)
Solutions
- Read the logged '分片上传TikTok视频失败' detail to identify which chunk and HTTP status failed; handle 401 by refreshing the access token and restarting the upload from a fresh init call.
- If the error indicates an expired/invalid upload_url, call initVideoUpload again to obtain a new URL and retry the full chunked upload.
- Add per-chunk retry with exponential backoff (chunks are idempotent per Content-Range only if TikTok supports resumable ranges — otherwise restart the upload).
- Verify video format/size meet TikTok requirements (mp4, within size/duration limits) before uploading.
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 instanceof BadRequestException) throw error; // preserve specific internal errors
if (error.response?.status === 401) {
throw new UnauthorizedException('TikTok 访问令牌已过期,请重新授权后重试');
}
throw new BadRequestException(`分片上传视频失败: ${error.response?.data?.error?.message || error.message}`);
} Defensive patterns
Strategy: retry
Validate before calling
if (!Buffer.isBuffer(videoBuffer) || videoBuffer.length === 0) {
throw new Error('videoBuffer must be a non-empty Buffer');
}
if (videoBuffer.length <= 10 * 1024 * 1024) {
// skip chunked path entirely; use single-shot upload
} Type guard
function isVideoBuffer(v) {
return Buffer.isBuffer(v) && v.length > 0;
} Try / catch
for (let attempt = 1; attempt <= 3; attempt++) {
try {
return await uploadVideo(accessToken, videoBuffer, initData);
} catch (e) {
if (!e.message.includes('分片上传视频失败') || attempt === 3) throw e;
initData = await initVideoUpload(accessToken, videoBuffer.length); // fresh URL
await new Promise(r => setTimeout(r, 2 ** attempt * 1000));
}
} Prevention
- Use files under 10MB where possible to avoid the chunked path.
- Re-init to get a fresh upload_url on every retry — URLs expire.
- Refresh the access token if it may be near expiry before a long upload.
- Confirm mp4 format and TikTok size limits before uploading.
- Monitor the logger output for the failing chunk index and HTTP status.
When it happens
Trigger: Any of: one of the 5MB chunk POSTs to upload_url returns a non-2xx status; the upload_url has expired (TikTok upload URLs are time-limited); Content-Range/Content-Length headers rejected; network interruption mid-upload; or the internal missing publish_id/upload_url throw bubbling into this catch.
Common situations: Videos where upload takes longer than TikTok's URL TTL, expired or revoked access tokens (401 from TikTok), file exceeding TikTok size/format limits mid-way, transient network failures on large multi-chunk uploads, and retrying after the URL already consumed.
Related errors
- 直接上传视频失败: ${error.response?.data?.error?.message || error.me
- 检查视频发布状态失败: ${error.response?.data?.error?.message || error.
- Relay uploadSign returned no uploadUrl: ${JSON.stringify(sig
- 上传视频失败,失败原因1:
- 交换授权码失败: ${error.response?.data?.error_description || error.
AI-assisted analysis of yikart/AiToEarn@d3aa8bea5b (2026-08-31).
Data as JSON: /api/errors/cebb06d773d2e02b.
Report an issue: GitHub.