{"record":{"id":"e6ae09500ce58fbf","repo":"yikart/AiToEarn","slug":"errhttpback-err-user-code-nohad","errorCode":"ErrHttpBack.err_user_code_nohad","errorMessage":"err_user_code_nohad","messagePattern":"err_user_code_nohad","errorType":"error_code","errorClass":"AppHttpException","httpStatus":400,"severity":"error","filePath":"project/aitoearn-electron/server/src/user/user.controller.ts","lineNumber":85,"sourceCode":"  }\n\n  @ApiOperation({\n    summary: '用户更新自己的电话号码',\n    description: '和手机验证码登录使用同一个验证码',\n  })\n  @Put('updatePhone')\n  async updatePhone(\n    @GetToken() token: TokenInfo,\n    @Body() body: LoginByPhoneDto,\n  ) {\n    const { phone, code } = body;\n\n    const res = await this.loginService.verifyPhoneCode(\n      phone,\n      code,\n      LoginTypeCacheKey.Code,\n    );\n    if (!res) throw new AppHttpException(ErrHttpBack.err_user_code_nohad);\n    return await this.userService.updateUserPhone(token.id, phone);\n  }\n}\n","sourceCodeStart":67,"sourceCodeEnd":89,"githubUrl":"https://github.com/yikart/AiToEarn/blob/d3aa8bea5b146a8675607cf0144d891aad3e9683/project/aitoearn-electron/server/src/user/user.controller.ts#L67-L89","documentation":"updatePhone validates the SMS code via loginService.verifyPhoneCode(phone, code, LoginTypeCacheKey.Code); a falsy result (missing, expired, or wrong code) throws err_user_code_nohad and the phone is not updated.","triggerScenarios":"PUT update-phone where the submitted code doesn't match the Redis value for that phone, or the 5-minute TTL expired.","commonSituations":"User typed the code wrong or waited >5 minutes; user requested a new code but entered the old one; dev environment where no SMS was actually sent; Redis restarted/flushed losing the key.","solutions":["Re-request a fresh verification code and submit it within 5 minutes","Check the code matches the most recent SMS for that phone","If testing outside production, use the returned/debug code instead of guessing","Verify Redis is running and persistent enough for the 5-minute window"],"exampleFix":"// before\nawait userApi.updatePhone(phone, oldCode); // expired\n// after\nawait loginService.postPhoneLoginCode(phone); // fresh code\nconst fresh = promptForCode();\nawait userApi.updatePhone(phone, fresh);","handlingStrategy":"validation","validationCode":"const stored = await redisService.get(`login:code:${phone}`);\nif (!stored) await loginService.postPhoneLoginCode(phone); // refresh code first","typeGuard":null,"tryCatchPattern":"try {\n  await userApi.updatePhone(phone, code);\n} catch (e) {\n  if (e.response?.message === 'err_user_code_nohad') {\n    await loginService.postPhoneLoginCode(phone); // resend then retry\n  }\n}","preventionTips":["Submit codes within the 5-minute TTL","Always use the latest SMS code after a resend","Show a countdown timer so users know when codes expire"],"tags":["sms","verification-code","redis","expired"],"backgroundTag":"invalid-verification-code","analyzedSha":"d3aa8bea5b146a8675607cf0144d891aad3e9683","analyzedAt":"2026-08-31T14:19:24.185Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}