You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

无法选中指定Game对象?分数增加功能抛出异常问题排查

问题排查与解决方案

核心问题分析

  1. findOne参数传递错误
    Sequelize的findOne仅接受单个配置对象,你当前将查询条件、排序/分页参数拆分为两个独立对象传入,导致排序和limit设置完全不生效,无法定位到用户最新的Game记录。同时如果用户无对应游戏记录,game会返回null,后续执行game.score += 1会直接抛出Cannot read properties of null异常。

  2. Game模型缺少createdAt字段
    你的SQL逻辑依赖createdAt排序,但当前Game模型未定义该字段,也未开启Sequelize自动时间戳功能,数据库表中不存在该字段,排序操作会触发SQL语法错误。


修复步骤

1. 修正findOne调用逻辑

合并所有查询选项到单个对象,并增加空值判断避免空指针异常:

exports.increaseScore = async (req, res) => {
    const userId = res.userId;

    try {
        // 将where、order、limit合并到同一配置对象
        const game = await Game.findOne({ 
            where: { userId: userId }, 
            limit: 1, 
            order: [['createdAt', 'DESC']] 
        });

        // 无对应记录时直接返回提示
        if (!game) {
            return res.status(404).json("未找到该用户的游戏记录");
        }

        game.score += 1;
        await game.save();
        res.status(200).json("分数增加成功!");
    } catch (err) {
        res.status(400).json(err.message || "操作失败");
    }
};

2. 完善Game模型的时间戳配置

两种可选方案:

方案一:开启自动时间戳(推荐)

让Sequelize自动生成createdAt和updatedAt字段:

const Game = sequelize.define("Games", {
    id: {
        type: Sequelize.INTEGER,
        autoIncrement: true,
        primaryKey: true,
        unique: true,
    },
    score: {
        type: Sequelize.INTEGER,
        allowNull: false
    },
    difficulty: {
        type: Sequelize.INTEGER,
        allowNull: false
    },
}, {
    timestamps: true,
    freezeTableName: true // 保持表名为Games,不自动复数化
});

exports.Game = Game;

方案二:手动定义createdAt字段

若不需要自动时间戳,手动添加字段定义:

const Game = sequelize.define("Games", {
    id: {
        type: Sequelize.INTEGER,
        autoIncrement: true,
        primaryKey: true,
        unique: true,
    },
    score: {
        type: Sequelize.INTEGER,
        allowNull: false
    },
    difficulty: {
        type: Sequelize.INTEGER,
        allowNull: false
    },
    createdAt: {
        type: Sequelize.DATE,
        allowNull: false,
        defaultValue: Sequelize.NOW
    }
});

exports.Game = Game;

3. 更新数据库表结构(开发环境)

执行模型同步更新表结构(生产环境建议用迁移脚本):

// 在关联关系定义后执行
sequelize.sync({ alter: true });

内容的提问来源于stack exchange,提问作者Gábor Kiss

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 20:24:54