yikart/AiToEarn · error · BadRequestException
获取视频详情失败: ${error.response?.data?.error?.message || error.me
Error message
获取视频详情失败: ${error.response?.data?.error?.message || error.message} What it means
getVideoDetail catches any error from TikTok's video-detail (query) endpoint and re-throws it as a 400 BadRequestException prefixed '获取视频详情失败:' with TikTok's error message (error.response.data.error.message) or the transport error message. Like 418, the actual cause lives in the embedded message — typically auth or an invalid video_id/fields combination.
Source
Thrown at project/aitoearn-electron/server/src/modules/plat/tiktok/tiktok.service.ts:104
videoId: string
): Promise<any> {
try {
const { data } = await firstValueFrom(
this.httpService.get(`${this.apiBaseUrl}/v2/video/info/`, {
params: {
fields: 'id,create_time,video_description,duration,height,width,share_count,comment_count,like_count,view_count,title,embed_link,embed_html,thumbnail_url',
video_id: videoId
},
headers: {
'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}`);
}
}
/**
* 方式1:初始化视频上传(旧版)
* @param accessToken 访问令牌
* @param videoSize 视频文件总大小(字节)
* @param chunkSize 分片大小(字节),默认为5MB
* @returns 初始化结果,包含上传所需的参数
*/
async initVideoUpload(
accessToken: string,
videoSize?: number,
chunkSize: number = 5 * 1024 * 1024 // 默认5MB
): Promise<any> {
try {
const requestBody: any = {};
View on GitHub (pinned to d3aa8bea5b)
Solutions
- Inspect the embedded error.message to get TikTok's precise error code.
- Refresh the account's access token if the message indicates token expiry/invalidity.
- Verify the videoId exists and is accessible to the authorizing account.
- Restrict the fields parameter to values allowed by TikTok's video-query API and the token scopes.
Example fix
// before
const detail = await tiktokService.getVideoDetail(token, videoId);
// after
try {
const detail = await tiktokService.getVideoDetail(token, videoId);
} catch (e) {
if (String(e.message).includes('invalid video_id')) return null; // video gone
throw e;
} Defensive patterns
Strategy: try-catch
Validate before calling
if (!accessToken) throw new Error('Missing TikTok access token');
if (!videoId || typeof videoId !== 'string') throw new Error('A valid videoId is required'); Type guard
function isVideoGone(msg: string): boolean {
return /video_id|invalid|not.?found|deleted/i.test(msg);
} Try / catch
try {
return await api.post('/tiktok/video/detail', { accountId, videoId });
} catch (e) {
const msg = e.response?.data?.message || e.message;
if (isTokenError(msg)) return retryWithRefreshedToken();
if (isVideoGone(msg)) return null; // treat deleted/private videos as absent
throw e;
} Prevention
- Treat 'not found'-style embedded messages as data-absence, not crashes.
- Keep the fields list in sync with TikTok's video-query API and token scopes.
- Refresh tokens for dormant accounts before querying details.
- Distinguish sandbox vs production tokens per environment to avoid 401-style upstream rejections.
When it happens
Trigger: Querying video details with an invalid or deleted videoId, an expired access token, disallowed field names, or while TikTok is unreachable/rate-limited.
Common situations: Videos deleted or made private on TikTok after being indexed; tokens expired for accounts unused for a long time; requesting fields not in the token's scopes; wrong environment (sandbox vs production) tokens.
Related errors
- 获取视频列表失败: ${error.response?.data?.error?.message || error.me
- 初始化视频上传失败: ${error.response?.data?.error?.message || error.m
- 初始化视频发布失败: ${error.response?.data?.error?.message || error.m
- 上传视频失败: ${error.response?.data?.error?.message || error.mess
- No response from Gemini
AI-assisted analysis of yikart/AiToEarn@d3aa8bea5b (2026-08-31).
Data as JSON: /api/errors/df9e14663203031c.
Report an issue: GitHub.