{"record":{"id":"05fa104b51b7c5ae","repo":"yikart/AiToEarn","slug":"video-upload-failed","errorCode":null,"errorMessage":"Video upload failed","messagePattern":"Video upload failed","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"project/aitoearn-electron/server/src/modules/plat/youtube/youtube.service.ts","lineNumber":1055,"sourceCode":"\n      // 调用 YouTube API 上传视频\n      const response = await this.youtubeService.playlistItems.insert(\n        {\n          auth: oauth2Client,\n          part: 'snippet,status, id, contentDetails',\n          requestBody\n        }\n      );\n\n    //   const response = {    \"data\": {\n    //     \"id\": \"7RckZHFBu7A\"\n    // },}\n      // 返回上传的视频 ID\n      if (response.data) {\n        console.log('Playlist insert successfully:', response.data);\n        return response.data;\n      } else {\n        throw new Error('Video upload failed');\n      }\n    } catch (error) {\n      console.error('Error uploading video:', error);\n      throw error;\n    }\n\n  }\n\n\n  /**\n * 获取播放列表项。\n */\n    async getPlayItemsList(accessToken, playlistId, itemsIds, maxResults, pageToken) {\n      // 设置 OAuth2 客户端凭证\n      this.oauth2Service.setCredentials(accessToken);\n      const oauth2Client = this.oauth2Service.getClient();\n\n    // 根据传入的参数来选择一个有效的请求参数","sourceCodeStart":1037,"sourceCodeEnd":1073,"githubUrl":"https://github.com/yikart/AiToEarn/blob/d3aa8bea5b146a8675607cf0144d891aad3e9683/project/aitoearn-electron/server/src/modules/plat/youtube/youtube.service.ts#L1037-L1073","documentation":"After a playlist insert (videos.insert/upload flow) the service checks response.data and throws a generic Error('Video upload failed') when the response body is falsy, i.e. Google returned 2xx without usable payload data. It is a weak success-check: the real cause is hidden and the console.error in the catch rethrows whatever preceded it.","triggerScenarios":"The YouTube API call resolves but response.data is undefined/null/empty object; network proxies or retry layers returning empty 2xx bodies; upstream error thrown earlier and rethrown through this catch with this message logged context.","commonSituations":"Rate-limited or flaky networks producing empty responses; misconfigured request part/body so the API returns 204/no content; stale tokens causing an earlier failure that surfaces only through the generic catch.","solutions":["Log the full response (status, headers, body) before this check to see why data is missing.","Verify the upload request builds correct metadata (snippet, status) and required parts.","Check token validity and quota (upload quota 403/412) — a failed call may surface as empty data.","Add explicit response.status check (e.g. require 200/201) and include status in the thrown message.","Retry the upload once after confirming network/proxy stability."],"exampleFix":"// before\nif (response.data) { return response.data; } else { throw new Error('Video upload failed'); }\n// after\nif (response.status === 200 && response.data?.id) { return response.data; }\nthrow new Error(`Video upload failed: status=${response.status} body=${JSON.stringify(response.data)}`);","handlingStrategy":"try-catch","validationCode":"if (!response || typeof response.status !== 'number') throw new Error('No response received from YouTube API');","typeGuard":"function hasUploadPayload(res: { status?: number; data?: { id?: string } | null }): res is { status: number; data: { id: string } } {\n  return typeof res.status === 'number' && !!res.data && typeof res.data.id === 'string';\n}","tryCatchPattern":"try {\n  const result = await client.uploadVideo(accountId, file);\n  if (!result?.id) throw new Error(`Upload returned no id: ${JSON.stringify(result)}`);\n} catch (error) {\n  console.error('Upload failed:', { status: error?.response?.status, data: error?.response?.data, message: error?.message });\n  // retry once with backoff for transient/network errors, then surface details\n}","preventionTips":["Log full response status+body at the throw site for diagnosability.","Check response.status and data.id, not truthiness of data alone.","Confirm quota and token validity before large uploads.","Add a bounded retry with backoff for transient failures."],"tags":["youtube-api","upload","empty-response","generic-error"],"backgroundTag":"empty-api-response","analyzedSha":"d3aa8bea5b146a8675607cf0144d891aad3e9683","analyzedAt":"2026-08-31T14:19:24.185Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}