Express.js注册功能报错:TypeError: Cannot read properties of undefined (reading 'id')
问题排查与修复
直接触发错误的原因
你遇到的TypeError: Cannot read properties of undefined (reading 'id'),核心问题是模型未定义email字段,且存在多处代码逻辑错误,导致Users.create()执行失败或返回无效实例:
模型缺少
email字段定义
在Users.init()的属性列表中,完全没有声明email字段,而你注册时传入了email参数。如果数据库表中email是必填项,create操作会直接失败并抛出错误,导致user变量为undefined,后续访问user.id自然会触发报错。字段命名不匹配
模型中用了firstName/lastName,但接口和控制器中用的是first_name/last_name,Sequelize默认不会自动转换命名风格,导致这些字段无法正确写入数据库,进一步引发创建失败。ID字段无自增配置
模型中id仅设置为primaryKey,但缺少autoIncrement: true,创建用户时如果不手动传入id,数据库无法自动生成ID值,会导致user.id为undefined或创建失败。错误的用户存在性检查
Users.find(email)不是Sequelize的合法方法,正确写法是Users.findOne({ where: { email } }),原代码会直接抛出方法不存在的错误,破坏流程。类型注解与异步逻辑错误
bcrypt.hash返回字符串,不能注解为typeof Usersjwt.sign是同步方法,不需要await,同样不能注解为typeof Users- catch块仅打印日志,未向客户端返回错误响应,会导致请求挂起
修复后的代码
模型文件Users.ts
interface UserAttributes { id: number; first_name: string; last_name: string; password: string; email:string; token: string; description?: string; createdAt?: Date; updatedAt?: Date; deletedAt?: Date; } 'use strict'; const { Model } = require('sequelize'); module.exports = (sequelize, DataTypes) => { class Users extends Model<UserAttributes> { public id!: number; public first_name!: string; public last_name!:string; public email!: string; public password!: string; public token!: string; public readonly createdAt!: Date; public readonly updatedAt!: Date; public readonly deletedAt?: Date; static associate(models) { // 定义关联(如有需要) } } Users.init({ id: { type: DataTypes.INTEGER, primaryKey: true, autoIncrement: true // 添加自增配置 }, password: DataTypes.STRING, first_name: DataTypes.STRING, // 统一为下划线命名 last_name: DataTypes.STRING, email: DataTypes.STRING, // 新增email字段定义 token: DataTypes.STRING, }, { sequelize, modelName: 'Users', tableName: 'users', // 如果数据库表所有字段都是下划线风格,可开启此配置自动转换命名 // underscored: true, }); return Users; };
注册控制器代码
async function Register(req: Request, res: Response): Promise<Response> { try { const { first_name, last_name, email, password } = req.body; // 检查用户是否已存在 const existingUser = await Users.findOne({ where: { email: email.toLowerCase() } }); if (existingUser) { return res.status(409).json({ error: '该邮箱已被注册' }); } // 加密密码 const encrypt: string = await bcrypt.hash(password, 10); // 创建用户 const user = await Users.create({ first_name, last_name, email: email.toLowerCase(), password: encrypt }); // 生成JWT token(同步方法,无需await) const token: string = jwt.sign( { user_id: user.id.toString(), email: user.email }, process.env.TOKEN_SECRET as string ); // 更新并保存token到数据库 user.token = token; await user.save(); // 创建成功用201状态码更符合REST规范 return res.status(201).json(user); } catch (error) { console.error('User couldnt be registered', error); // 返回错误响应给客户端 return res.status(500).json({ error: '注册失败,请稍后重试' }); } };
内容的提问来源于stack exchange,提问作者user18644175
相关产品推荐
相关产品推荐

