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

Mongoose与MongoDB:日期字段处理及更新截止日期避崩溃咨询

问题:Node.js/Express/MongoDB应用批量更新任务截止日期时崩溃

我正在开发基于Node.js、Express、Mongoose和MongoDB的应用,需实现任务截止日期每24小时自动刷新功能,但更新时应用崩溃。

相关代码

Task.js(模型)

const mongoose = require('mongoose');
const taskSchema = new mongoose.Schema({
    name: { type: String, required: true },
    description: { type: String, required: true },
    dueDate: { type: Date, required: true },
    assignedTo: { type:mongoose.Schema.Types.ObjectId, ref: 'User' },
    status: { type: Boolean, default: false },
    
})

taskControllers.js

const updateDueDate = async (req, res) => {
    const { dueDate } = req.body;

    if (!dueDate || isNaN(new Date(dueDate).getTime())) {
        return res.status(400).json({ message: 'Invalid due date' });
    }
    try {
        const tasks = await Task.find({});
        await Promise.all(tasks.map(async (task) => {
            task.dueDate = new Date(dueDate);
            await task.save();
        }).catch(err => {
            return res.status(400).json({ err: err.message });
        }));

        res.status(200).json({ message: 'Duedates updated });
    } catch (err) {
        console.error('Error updating due dates:', err);
        res.status(500).json({ message: 'Error updating duedates', error: err.message });
    }
};

TaskDetails.js(前端)

useEffect(() => {
    const fetchTasks = async () => {
      try {
        const response = await axios.get('/api/users/{user.id}/tasks'); 
        setDailyTasks(response.data.tasks);
      } catch (error) {
        console.error('Error fetching tasks:', error);
      }
    };

    fetchTasks();
  }, [setDailyTasks]);

  useEffect(() => {
    const refreshDueDate = async () => {
      const newDueDate = new Date(Date.now() + 24 * 60 * 60 * 1000).toISOString();
      try {
        const response = await axios.put(`/api/tasks/due`, { dueDate: newDueDate });
        setDailyTasks(prevTasks => prevTasks.map(task => ({
          ...task,
          dueDate: newDueDate,
        })));
        console.log('Duedate updated!', response.data);
      } catch (error) {
        console.error('Error updating duedate', error);
      }
    };
 
    const interval = setInterval(refreshDueDate, 24 * 60 * 60 * 1000);

    refreshDueDate();

    return () => clearInterval(interval);
  }, [setDailyTasks]);

报错信息

更新时应用崩溃,日志显示:

SyntaxError: Unexpected end of JSON input
at JSON.parse ()
MongoError: BSONError: input must be a 24 character hex string, 12 byte Uint8Array, or an integer

问题

  1. 如何确保日期格式正确并安全保存至MongoDB,避免崩溃?
  2. 有没有更优的日期更新方式,规避BSON格式问题?
  3. 在Mongoose和MongoDB中管理日期字段,我是否遗漏了最佳实践?

已尝试方案

  • 确认Mongoose Schema中dueDate字段为Date类型;
  • 将日期转为ISO字符串后发送至后端;
  • 添加详细错误日志定位故障。

解决方案

1. 修复致命错误,确保日期安全保存

先解决导致崩溃的直接问题:

  • 修复JSON语法错误:taskControllers.js中响应的JSON字符串未闭合,改为:

    res.status(200).json({ message: 'Duedates updated' });
    

    这个错误会直接引发前端解析响应时的SyntaxError。

  • 修正Promise错误处理位置:将catch绑定在Promise.all而非map方法后,避免数组混入错误处理返回值:

    await Promise.all(tasks.map(async (task) => {
        task.dueDate = new Date(dueDate);
        await task.save();
    })).catch(err => {
        return res.status(400).json({ err: err.message });
    });
    
  • 修复前端请求路径:将硬编码的{user.id}改为模板字符串语法,确保请求URL有效:

    const response = await axios.get(`/api/users/${user.id}/tasks`);
    
  • 增强日期验证:优化后端验证逻辑,确保解析后的日期有效:

    const parsedDate = new Date(dueDate);
    if (!dueDate || isNaN(parsedDate.getTime())) {
        return res.status(400).json({ message: 'Invalid due date' });
    }
    

2. 更优的批量更新方式

当前逐个查询保存的方式效率低且易引发并发问题,改用updateMany批量更新,直接规避BSON相关错误:

const updateDueDate = async (req, res) => {
    const { dueDate } = req.body;
    const parsedDate = new Date(dueDate);

    if (!dueDate || isNaN(parsedDate.getTime())) {
        return res.status(400).json({ message: 'Invalid due date' });
    }
    try {
        // 一次请求完成所有任务的截止日期更新
        await Task.updateMany({}, { $set: { dueDate: parsedDate } });
        res.status(200).json({ message: 'Duedates updated' });
    } catch (err) {
        console.error('Error updating due dates:', err);
        res.status(500).json({ message: 'Error updating duedates', error: err.message });
    }
};

3. Mongoose/MongoDB日期管理最佳实践

  • Schema层添加日期验证:在Task模型中提前拦截无效日期:

    dueDate: { 
        type: Date, 
        required: true,
        validate: {
            validator: function(v) {
                return !isNaN(v.getTime());
            },
            message: props => `${props.value} is not a valid date!`
        }
    }
    
  • 优先使用原生Date对象:始终以Date类型存储日期,Mongoose会自动处理BSON转换,避免字符串存储带来的解析问题。

  • 后端定时任务替代前端轮询:前端setInterval在页面关闭后失效,改用后端定时任务(如node-schedule)实现自动更新:

    const schedule = require('node-schedule');
    // 每天凌晨自动更新所有任务截止日期
    schedule.scheduleJob('0 0 * * *', async () => {
        const newDueDate = new Date(Date.now() + 24 * 60 * 60 * 1000);
        await Task.updateMany({}, { $set: { dueDate: newDueDate } });
        console.log('Automatically updated task due dates');
    });
    
  • 避免不必要的日期转换:Mongoose返回的日期会自动转为ISO字符串,前端可直接使用;后端接收ISO字符串时,new Date()可直接解析为有效Date对象。


内容的提问来源于stack exchange,提问作者Nutan Nimkar

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 05:17:37