{"record":{"id":"61399e7f7773a055","repo":"yikart/AiToEarn","slug":"errhttpback-err-user-code-send-fail","errorCode":"ErrHttpBack.err_user_code_send_fail","errorMessage":"err_user_code_send_fail","messagePattern":"err_user_code_send_fail","errorType":"error_code","errorClass":"AppHttpException","httpStatus":400,"severity":"error","filePath":"project/aitoearn-electron/server/src/user/login.service.ts","lineNumber":40,"sourceCode":"  constructor(\n    private readonly redisService: RedisService,\n    private readonly alicloudSmsService: AlicloudSmsService,\n  ) {}\n\n  /**\n   * 发送手机号注册的验证码\n   * @param phone\n   */\n  async postPhoneRegisterCode(phone: string) {\n    const cacheKey = `${LoginTypeCacheKey.Password}:${phone}`;\n    let code = await this.redisService.get(cacheKey);\n    if (code) throw new AppHttpException(ErrHttpBack.err_user_code_had);\n\n    code = getRandomString(6, true);\n    const res = await this.alicloudSmsService.sendLoginSms(phone, code);\n\n    if (process.env.NODE_ENV === 'production') {\n      if (!res) throw new AppHttpException(ErrHttpBack.err_user_code_send_fail);\n    }\n\n    this.redisService.setKey(cacheKey, code, 60 * 5);\n    console.log('发送短信成功', code);\n\n    return process.env.NODE_ENV === 'production' ? res : code;\n  }\n\n  /**\n   * 发送手机号登录的验证码\n   * @param phone\n   */\n  async postPhoneLoginCode(phone: string) {\n    const cacheKey = `${LoginTypeCacheKey.Code}:${phone}`;\n    let code = await this.redisService.get(cacheKey);\n    if (code) throw new AppHttpException(ErrHttpBack.err_user_code_had);\n\n    code = getRandomString(6, true);","sourceCodeStart":22,"sourceCodeEnd":58,"githubUrl":"https://github.com/yikart/AiToEarn/blob/d3aa8bea5b146a8675607cf0144d891aad3e9683/project/aitoearn-electron/server/src/user/login.service.ts#L22-L58","documentation":"AppHttpException with ErrHttpBack.err_user_code_send_fail (errCode 40020, message '验证码发送失败'). Thrown by LoginService.postPhoneRegisterCode (login.service.ts:40) when NODE_ENV=production and alicloudSmsService.sendLoginSms returns a falsy result, meaning AliCloud SMS failed to send the code. In non-production the SMS call result is not enforced (the code is returned directly).","triggerScenarios":"Requesting a register SMS code in a production deployment where alicloudSmsService.sendLoginSms(phone, code) resolves to null/false — SMS provider rejects or fails the send.","commonSituations":"Missing or invalid AliCloud SMS credentials (accessKeyId/secret, sign name, template code); phone number rejected (invalid format, blacklist, throttling by AliCloud); SMS account balance exhausted or template not approved for the region.","solutions":["Check AliCloud SMS credentials and configuration (access key, signature, template id) in the production env","Inspect the AliCloud SMS API response/logs for the reject reason (throttle, invalid phone, blacklisted)","Verify the SMS account has balance and the template/signature are approved","Only set NODE_ENV=production after SMS is verified working, since enforcement only happens in production"],"exampleFix":"// env\n// before\nALICLOUD_SMS_TEMPLATE=unset\n// after\nALICLOUD_ACCESS_KEY=xxx\nALICLOUD_SMS_SIGN=AiToEarn\nALICLOUD_SMS_TEMPLATE=SMS_123456789","handlingStrategy":"try-catch","validationCode":"// pre-flight: verify SMS config is reachable before user flows\nconst cfgOk = !!(process.env.ALICLOUD_ACCESS_KEY && process.env.ALICLOUD_SMS_SIGN && process.env.ALICLOUD_SMS_TEMPLATE)\nif (!cfgOk) throw new Error('AliCloud SMS configuration missing')","typeGuard":"function isSmsConfigured(cfg: Partial<SmsConfig>): cfg is SmsConfig {\n  return Boolean(cfg.accessKey && cfg.sign && cfg.templateCode)\n}","tryCatchPattern":"try {\n  await api.postPhoneRegisterCode(phone)\n} catch (e) {\n  if (e?.errCode === '40020') {\n    // log SMS failure details, surface a retry-with-backoff message to the user\n  } else throw e\n}","preventionTips":["Validate AliCloud SMS credentials, signature and template at service startup","Monitor SMS account balance and provider error rates","Test sendLoginSms in a staging environment with production-like credentials before release"],"tags":["sms","alicloud","external-service","configuration"],"backgroundTag":"external-sms-send-failed","analyzedSha":"d3aa8bea5b146a8675607cf0144d891aad3e9683","analyzedAt":"2026-08-31T14:19:24.185Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}