{"record":{"id":"9fdb5063f80aa854","repo":"yikart/AiToEarn","slug":"videoid-userid-accountid","errorCode":null,"errorMessage":"videoId, userId和accountId是必须的","messagePattern":"videoId, userId和accountId是必须的","errorType":"validation","errorClass":"BadRequestException","httpStatus":400,"severity":"error","filePath":"project/aitoearn-electron/server/src/modules/plat/tiktok/tiktok.controller.ts","lineNumber":362,"sourceCode":"    schema: {\n      type: 'object',\n      properties: {\n        accountId: { type: 'string', description: 'TikTok账号ID' },\n        videoId: { type: 'string', description: '视频ID' },\n        rating: { type: 'string', description: '操作类型: like 或 unlike' }\n      },\n      required: ['accountId', 'videoId', 'rating']\n    }\n  })\n  async rateVideo(\n    @GetToken() systemToken: TokenInfo,\n    @Body('videoId') videoId: string,\n    @Body('accountId') accountId: string,\n    @Body('rating') rating: string\n  ) {\n    const userId = systemToken.id;\n    if (!videoId || !userId || !accountId) {\n      throw new BadRequestException('videoId, userId和accountId是必须的');\n    }\n\n    const accessToken = await this.tikTokAuthService.getUserAccessToken(accountId);\n\n    // 在方法开始处验证\n    if (![\"like\", \"unlike\"].includes(rating)) {\n      throw new BadRequestException('参数错误: rating必须为like或unlike');\n    }\n\n    // 后续处理\n    if (rating === \"like\") {\n      return this.tikTokService.likeVideo(accessToken, userId, accountId, videoId);\n    } else {\n      return this.tikTokService.unlikeVideo(accessToken, userId, accountId, videoId);\n    }\n  }\n\n  /**","sourceCodeStart":344,"sourceCodeEnd":380,"githubUrl":"https://github.com/yikart/AiToEarn/blob/d3aa8bea5b146a8675607cf0144d891aad3e9683/project/aitoearn-electron/server/src/modules/plat/tiktok/tiktok.controller.ts#L344-L380","documentation":"rateVideo validates that videoId, accountId (from the body) and userId (derived from the authenticated token) are all present before doing anything. A 400 BadRequestException is thrown when any is missing. Note userId comes from systemToken.id, so this error for userId implies the auth token was absent/invalid.","triggerScenarios":"Calling the rate-video endpoint without videoId or accountId in the body, or calling it without a valid auth token so systemToken.id is undefined.","commonSituations":"Anonymous/unauthenticated requests reaching the endpoint; scripts replaying the endpoint without body fields; account not selected in the UI so accountId is empty.","solutions":["Include videoId and accountId in the request body.","Attach a valid authentication token so systemToken.id resolves to a userId.","Validate body fields on the client before dispatching the request."],"exampleFix":"// before\nawait api.post('/tiktok/video/rate', { videoId });\n// after\nawait api.post('/tiktok/video/rate', { videoId, accountId, rating: 'like' });","handlingStrategy":"validation","validationCode":"if (!videoId || !accountId || !authToken) {\n  throw new Error('videoId, accountId and a valid auth token are required');\n}","typeGuard":"function canRate(p: { videoId?: string; accountId?: string }): p is { videoId: string; accountId: string } {\n  return typeof p.videoId === 'string' && p.videoId !== '' &&\n         typeof p.accountId === 'string' && p.accountId !== '';\n}","tryCatchPattern":"try {\n  await api.post('/tiktok/video/rate', { videoId, accountId, rating });\n} catch (e) {\n  if (e.response?.status === 401 || e.response?.status === 400) {\n    await reauthenticate();\n  }\n}","preventionTips":["Always send requests through an authenticated API client that attaches the token.","Disable rate controls in the UI until an accountId is selected.","Validate body fields at the boundary of your client code, not just at the server."],"tags":["bad-request","validation","tiktok","missing-parameter","auth"],"backgroundTag":"missing-required-parameter","analyzedSha":"d3aa8bea5b146a8675607cf0144d891aad3e9683","analyzedAt":"2026-08-31T14:19:24.185Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}