使用YouTube API批量添加视频到播放列表时出现500错误求助
问题背景
通过YouTube Search API获取视频ID后,用循环批量调用API将视频添加到指定播放列表,部分请求返回500内部错误(backendError),单独请求可成功,已尝试添加延迟、Axios拦截器但未解决。
错误信息:
{ "error": { "code": 500, "message": "Internal error encountered.", "errors": [ { "message": "Internal error encountered.", "domain": "global", "reason": "backendError" } ], "status": "INTERNAL" } }
循环逻辑代码:
for (let i = 0; i < videoList.length; i++) { params.q = checkValue[i]; await searchVideo(params).then((res) => { try { addToPlayList(playlistId, res.items[0].id.videoId); } catch (error) { console.log(error); } }); }
Axios请求代码:
baseInstance .post( `https://www.googleapis.com/youtube/v3/playlistItems?&part=snippet&resource.snippet.playlistId=${playlistId}&resource.snippet.resourceId.videoId=${vid}&resource.snippet.resourceId.kind=youtube%23video` )
可能的原因及修复建议
1. 并发请求未被有效控制
你的循环中,await仅作用于searchVideo,但addToPlayList是异步调用且未加await,导致循环会快速触发多个addToPlayList请求,形成隐性并发。YouTube API对并发连接数和请求速率有隐性限制,当并发量过高时,后台可能抛出backendError。
修复:
确保addToPlayList被await,让请求串行执行;如果需要提高效率,可使用并发控制工具限制同时发起的请求数:
for (let i = 0; i < videoList.length; i++) { params.q = checkValue[i]; const res = await searchVideo(params); try { // 添加await确保串行执行 await addToPlayList(playlistId, res.items[0].id.videoId); // 可选:添加短延迟,进一步降低触发限制的概率 await new Promise(resolve => setTimeout(resolve, 1000)); } catch (error) { console.error(`添加视频失败:${res.items[0].id.videoId}`, error); } }
2. POST请求参数格式不符合API规范
YouTube API创建播放列表项(playlistItems.insert)要求将snippet数据放在请求体中,而非URL参数里。虽然单独请求可能因后台兼容通过,但批量请求时这种不规范的参数传递容易触发后台处理异常,返回500错误。
修复:
修改Axios请求,将参数移至请求体:
baseInstance.post( 'https://www.googleapis.com/youtube/v3/playlistItems?part=snippet', { snippet: { playlistId: playlistId, resourceId: { kind: 'youtube#video', videoId: vid } } } )
3. 缺少针对backendError的重试机制
backendError属于YouTube后台的临时异常,并非请求本身的永久错误。你的代码没有对这类错误进行重试,导致部分临时失败的请求直接被判定为错误。
修复:
在addToPlayList函数中添加重试逻辑,针对500错误自动重试2-3次:
async function addToPlayList(playlistId, vid) { let retryCount = 0; const maxRetries = 3; while (retryCount < maxRetries) { try { return await baseInstance.post( 'https://www.googleapis.com/youtube/v3/playlistItems?part=snippet', { snippet: { playlistId: playlistId, resourceId: { kind: 'youtube#video', videoId: vid } } } ); } catch (error) { if (error.response?.status === 500 && retryCount < maxRetries - 1) { retryCount++; await new Promise(resolve => setTimeout(resolve, 2000 * retryCount)); // 指数退避延迟 continue; } throw error; } } }
4. 隐性权限/视频属性问题
部分视频可能存在版权限制(如不允许被添加到第三方播放列表),但YouTube API未返回明确的权限错误,而是抛出了通用的500错误。虽然单独请求时可能刚好避开,但批量请求时会触发这类异常。
排查:
记录每个失败请求对应的视频ID,单独测试这些视频是否能成功添加,确认是否存在权限问题。
内容的提问来源于stack exchange,提问作者ChagHeon Yoo

