Mongoose 验证错误发生在 OpenShift 而不是本地版本
Mongoose Validation Error occurs on OpenShift but not local version
我正在将我的 Node.js 使用 Mongoose 的服务器迁移到 OpenShift,实时服务器上发生错误,我无法在我的本地 WebStorm 内置服务器上重现该错误。
我收到错误消息:
undefined: {
properties: {
message: "Cannot read property 'options' of undefined"
type: "cast"
}-
message: "Cannot read property 'options' of undefined"
name: "ValidatorError"
kind: "cast"
}
当我尝试将元素推入 items
数组并保存时,会出现以下模式:
var listSchema = new mongoose.Schema({
owner: {type: mongoose.Schema.Types.ObjectId, ref: 'User', required: true},
name: {type: String, required: true},
items: [
{
name:{
type: String,
required:true
},
quantity:Number,
check: Boolean
}
]
});
有效的本地版本和 OpenShift 版本使用完全相同的代码。添加新元素的代码是:
var listId = req.params["id"];
if (sessions.verifyToken(userId, token)) {
var data = req.body;
var query = List.findOne({
owner: userId,
"_id": listId
});
query.exec(function(err, list) {
...
//handle error and null (omitted for brevity)
...
list.items.push({ // error thrown here
name: req.body["name"],
quantity: req.body["quantity"],
check: false
});
list.save(function(err, list) {
if (err) {
var message = "Unable save appended list to persistent memory";
console.log(message, err);
res.setHeader("content-type", "application/json");
res.send(JSON.stringify({success: false, message: message, error: err}));
return;
}
res.setHeader("content-type", "application/json");
res.send(JSON.stringify(list));
});
});
我认为可能是早期版本的架构添加了约束,所以我删除了 lists
集合,但问题并没有消失。
OpenShift PaaS 上可能有什么不同可能导致错误?
[编辑]
只是为了好玩,我从 items
中删除了所有必填字段,现在错误消息是这样的:
"undefined": {
"properties": {
"message": "Cannot read property 'options' of undefined",
"type": "cast"
},
"message": "Cannot read property 'options' of undefined",
"name": "ValidatorError",
"kind": "cast"
},
"owner": {
"properties": {
"type": "required",
"message": "Path `{PATH}` is required.",
"path": "owner"
},
"message": "Path `owner` is required.",
"name": "ValidatorError",
"kind": "required",
"path": "owner"
}
这似乎表明模型在查找列表和再次保存之间的某处丢失了其 owner
字段。
[/编辑]
在 OpenShift 上,当您 find
或 findOne
一个需要引用另一个实体的模型时,该字段不会自动填写。因此,当 save
是调用,该字段将丢失。改变
var query = List.findOne({
owner: userId,
"_id": listId
});
到
var query = List.findOne({
owner: userId,
"_id": listId
}).populate("owner");
出于某种原因,这在每个环境中的工作方式都不一样。对于某些人来说,它要么自动填充参考字段,要么在保存时假定它不变。我不确定是哪个。
我正在将我的 Node.js 使用 Mongoose 的服务器迁移到 OpenShift,实时服务器上发生错误,我无法在我的本地 WebStorm 内置服务器上重现该错误。
我收到错误消息:
undefined: {
properties: {
message: "Cannot read property 'options' of undefined"
type: "cast"
}-
message: "Cannot read property 'options' of undefined"
name: "ValidatorError"
kind: "cast"
}
当我尝试将元素推入 items
数组并保存时,会出现以下模式:
var listSchema = new mongoose.Schema({
owner: {type: mongoose.Schema.Types.ObjectId, ref: 'User', required: true},
name: {type: String, required: true},
items: [
{
name:{
type: String,
required:true
},
quantity:Number,
check: Boolean
}
]
});
有效的本地版本和 OpenShift 版本使用完全相同的代码。添加新元素的代码是:
var listId = req.params["id"];
if (sessions.verifyToken(userId, token)) {
var data = req.body;
var query = List.findOne({
owner: userId,
"_id": listId
});
query.exec(function(err, list) {
...
//handle error and null (omitted for brevity)
...
list.items.push({ // error thrown here
name: req.body["name"],
quantity: req.body["quantity"],
check: false
});
list.save(function(err, list) {
if (err) {
var message = "Unable save appended list to persistent memory";
console.log(message, err);
res.setHeader("content-type", "application/json");
res.send(JSON.stringify({success: false, message: message, error: err}));
return;
}
res.setHeader("content-type", "application/json");
res.send(JSON.stringify(list));
});
});
我认为可能是早期版本的架构添加了约束,所以我删除了 lists
集合,但问题并没有消失。
OpenShift PaaS 上可能有什么不同可能导致错误?
[编辑]
只是为了好玩,我从 items
中删除了所有必填字段,现在错误消息是这样的:
"undefined": {
"properties": {
"message": "Cannot read property 'options' of undefined",
"type": "cast"
},
"message": "Cannot read property 'options' of undefined",
"name": "ValidatorError",
"kind": "cast"
},
"owner": {
"properties": {
"type": "required",
"message": "Path `{PATH}` is required.",
"path": "owner"
},
"message": "Path `owner` is required.",
"name": "ValidatorError",
"kind": "required",
"path": "owner"
}
这似乎表明模型在查找列表和再次保存之间的某处丢失了其 owner
字段。
[/编辑]
在 OpenShift 上,当您 find
或 findOne
一个需要引用另一个实体的模型时,该字段不会自动填写。因此,当 save
是调用,该字段将丢失。改变
var query = List.findOne({
owner: userId,
"_id": listId
});
到
var query = List.findOne({
owner: userId,
"_id": listId
}).populate("owner");
出于某种原因,这在每个环境中的工作方式都不一样。对于某些人来说,它要么自动填充参考字段,要么在保存时假定它不变。我不确定是哪个。