Mongo .save() 在本地工作但在 Heroku 远程上有验证错误

Mongo .save() works locally but has validation errors on Heroku remote

我能够连接到我的 Mongo 数据库和我的数据,save() 在本地工作但自从推送到 Heroku 后我注意到保存触发验证错误。任何地方的日志中都没有任何内容。我有两个 post 路由调用 mongoose 保存函数,我在第二个函数中测试了 vs findOneAndUpdate 以排除这种情况,但验证错误仍然存​​在。我还尝试用我的中间件保护 post 路由,但仍然没有成功。我知道我会在编辑时遇到错误,在渲染时未定义字段,但保存函数仍应保存到另一个函数中的数据库中。

唯一显着的变化是集成了 auth0,所以我想也许我需要 运行 通过中间件的 post 路由,但这似乎也不起作用。

有效负载似乎已发送但未保存到数据库,关于如何获取更多信息或我可能遗漏的信息有什么建议吗?我知道有很多东西需要消化,但有什么想法吗?

postroutes.js

    const express = require('express');
    const router = express.Router();
    const mongoose = require('mongoose');
    const Booking = mongoose.model('Booking');

    router.post('/add', /* secured(), */(req, res) => {
        insertRecord(req, res);
    });
    function insertRecord(req, res) {
        const booking = new Booking();
        booking.firstName = req.body.firstName;
        booking.lastName = req.body.lastName;
        booking.customerEmail = req.body.customerEmail;
        booking.phone = req.body.phone;
        booking.pax = req.body.pax;
        booking.tourType = req.body.tourType;
        booking.operatorName = req.body.operatorName;
        booking.dateBooked = req.body.dateBooked;
        booking.tourDate = req.body.tourDate;
        booking.pickupAddress = req.body.pickupAddress;
        booking.notes = req.body.notes;
        booking.paidStatus = req.body.paidStatus;
        booking.guidesName = req.body.guidesName;
        booking.guidesEmail = req.body.guidesEmail;
        booking.clientReminderSent = req.body.clientReminderSent;
        booking.bookingCreatedSent = req.body.bookingCreatedSent;
        booking.calendarEventCreated = req.body.calendarEventCreated;
        booking.remindGoCapeGuides = req.body.remindGoCapeGuides;
        booking.remindOperators = req.body.remindOperators;
        booking.feedbackSent = req.body.feedbackSent;
        booking.save((err, doc) => {
            if (!err) {
                //  res.redirect('/list');
                res.render('add', {
                    viewTitle: 'Add New Booking',
                    booking: req.body,
                    saveSuccessful: 'Booking Saved',
                });

                console.log('Saved!');
            } else {
                if (err.name == 'ValidationError') {
                    handleValidationError(err, req.body);
                    res.render('add', {
                        viewTitle: 'Add New Booking',
                        booking: req.body,
                        saveUnsuccessful: 'Not Saved: ' + err + ' Error saving booking, please try again.',
                    });
                } else {
                    console.log('Error during record insertion : ' + err);
                }
            }
        });
    }

    router.post('/edit', (req, res) => {
        console.log(req.body._id);
        updateRecord(req, res);
    });

    function updateRecord(req, res) {
        const booking = new Booking();
        booking.firstName = req.body.firstName;
        booking.lastName = req.body.lastName;
        booking.customerEmail = req.body.customerEmail;
        booking.phone = req.body.phone;
        booking.pax = req.body.pax;
        booking.tourType = req.body.tourType;
        booking.operatorName = req.body.operatorName;
        booking.dateBooked = req.body.dateBooked;
        booking.tourDate = req.body.tourDate;
        booking.pickupAddress = req.body.pickupAddress;
        booking.notes = req.body.notes;
        booking.paidStatus = req.body.paidStatus;
        booking.guidesName = req.body.guidesName;
        booking.guidesEmail = req.body.guidesEmail;
        booking.clientReminderSent = req.body.clientReminderSent;
        booking.bookingCreatedSent = req.body.bookingCreatedSent;
        booking.calendarEventCreated = req.body.calendarEventCreated;
        booking.remindGoCapeGuides = req.body.remindGoCapeGuides;
        booking.remindOperators = req.body.remindOperators;
        booking.feedbackSent = req.body.feedbackSent;

        Booking.findOneAndUpdate({_id: req.body._id}, req.body, {new: true}, (err, doc) =>  {
            if (!err) {
                 res.redirect('/list');
               /* res.render('edit', {
                    viewTitle: 'Edit Booking',
                    booking: req.body,
                    saveSuccessful: 'Booking Updated',
                });*/
            } else {
                if (err.name == 'ValidationError') {
                    handleValidationError(err, req.body);
                    res.render('edit', {
                        viewTitle: 'Edit Booking',
                        booking: req.body,
                        saveUnsuccessful: 'Not Saved: Error saving booking, please try again.',
                    });
                } else {
                    console.log('Error during record update : ' + err);
                }
            }
        });
    }
    function handleValidationError(err, body) {
        // eslint-disable-next-line guard-for-in
        for (field in err.errors) {
            switch (err.errors[field].path) {
                case 'firstName':
                    body['firstNameError'] = err.errors[field].message;
                    break;
                case 'lastName':
                    body['lastNameError'] = err.errors[field].message;
                    break;
                case 'tourType':
                    body['tourTypeError'] = err.errors[field].message;
                    break;
                case 'dateBooked':
                    body['dateBookedError'] = err.errors[field].message;
                    break;
                case 'tourDate':
                    body['tourDateError'] = err.errors[field].message;
                    break;
                case 'pax':
                    body['paxError'] = err.errors[field].message;
                    break;
                case 'phone':
                    body['phoneError'] = err.errors[field].message;
                    break;
                case 'customerEmail':
                    body['customerEmailError'] = err.errors[field].message;
                    break;
                case 'pickupAddress':
                    body['pickupAddressError'] = err.errors[field].message;
                    break;
                case 'operatorName':
                    body['operatorNameError'] = err.errors[field].message;
                    break;
                case 'paidStatus':
                    body['paidStatusError'] = err.errors[field].message;
                    break;
                case 'notes':
                    body['paidStatusError'] = err.errors[field].message;
                    break;
                default:
                    break;
            }
        }
    }

    router.post('/search/:q', function (req, res) {
        const q = req.body.q;
        res.send(q);
        console.log(q);
    });

    module.exports = router;

routes.js

router.get('/add', secured(), (req, res, next) => {
// const {_raw, _json, ...userProfile} = req.user;
res.render('add', {
viewTitle: 'Add New Booking',
booking: req.body,
});
});

router.get('/edit/:id', secured(), (req, res) => {
    Booking.findById(req.params.id, (err, doc) => {
    if (!err) {
      res.render('edit', {
        viewTitle: 'Edit Booking',
        booking: doc,
      });
    }
  });
});

model.js

const mongoose = require('mongoose');

const bookingSchema = new mongoose.Schema({
  firstName: {
    type: String,
    required: 'This field is required',
  },
  lastName: {
    type: String,
    required: 'This field is required',
  },
  tourType: {
    type: String,
    required: 'This field is required',
  },
  dateBooked: {
    type: String,
    required: 'This field is required',
  },
  tourDate: {
    type: String,
    required: 'This field is required',
  },
  pax: {
    type: String,
    required: 'This field is required',
  },
  phone: {
    type: String,
    required: 'This field is required',
  },
  customerEmail: {
    type: String,
    required: 'This field is required',
  },
  pickupAddress: {
    type: String,
    required: 'This field is required',
  },
  operatorName: {
    type: String,
    required: 'This field is required',
  },
  paidStatus: {
    type: String,
    required: 'This field is required',
  },
  notes: {
    type: String,
  },
  guidesName: {
    type: String,
  },
  guidesEmail: {
    type: String,
  },
  bookingCreatedSent: {
    type: Boolean,
  },
  calendarEventCreated: {
    type: Boolean,
  },
  clientReminderSent: {
    type: Boolean,
  },
  remindOperators: {
    type: Boolean,
  },
  remindGoCapeGuides: {
    type: Boolean,
  },
  feedbackSent: {
    type: Boolean,
  },
});

// Custom validation for email
bookingSchema.path('customerEmail').validate((val) => {
  emailRegex = /^(([^<>()\[\]\.,;:\s@"]+(\.[^<>()\[\]\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
  return emailRegex.test(val);
}, 'Invalid e-mail.');

mongoose.model('Booking', bookingSchema);

如有任何建议,我们将不胜感激!

更新

我添加了 mongoose.set('debug', true); 以获取更多信息,但是当我 post 一个表单时,我在 Heroku 日志或其他任何地方都看不到任何内容,这可能是中间件吗?由于路由 /add 和 /edit 正在通过安全中间件,post 路由是否应该做同样的事情?

好的,在 body-parserexpress.json 之间切换进行测试时,我终于在日志中发现了一个错误,它导致我在另一个模块中出错,该模块没有被正确调用,但是依赖于保存,然后由于不正确的关闭和引用,它被挂起。看来现在一切都按预期再次工作。

在 body-parser 和 express.json 之间切换进行测试时,我终于在日志中发现错误,这导致我在另一个模块中出错,该模块未被正确调用但依赖于保存,然后由于不正确的关闭和引用,它被挂起。看来现在一切都按预期重新工作了。