我对这段代码中的两条路线有相同的逻辑,但它们的行为不同
I have the same logic for two routes in this code , but they behave differently
// @route GET api/profile/handle/:handle
// @desc Get profile by handle
// @access Public
router.get('/handle/:handle', (req, res) => {
const errors = {};
Profile.findOne({ handle: req.params.handle })
.populate('user', ['name', 'avatar'])
.then(profile => {
//console.log('profile1 ' + profile);
if (!profile) {
errors.noprofile = 'There is no profile for this user for handle route (from then block)';
res.status(404).json(errors);
}
res.json(profile);
})
.catch(err => res.status(404).json({ profile: 'There is no profile for this user for handle route (from error block)' }));
});
// @route GET api/profile/user/:user_id
// @desc Get profile by user ID
// @access Public
router.get('/user/:user_id', (req, res) => {
const errors = {};
Profile.findOne({ user: req.params.user_id })
.populate('user', ['name', 'avatar'])
.then(profile => {
// console.log('profile not found by userid');
//console.log('profile2 ' + profile);
if (!profile) {
errors.noprofile = 'There is no profile for this user for user_id route (from then block)';
res.status(404).json(errors);
}
res.json(profile);
})
.catch(err => res.status(404).json({ profile: 'There is no profile for this user for user_id route (from error block)',
err: err }));
});
我有上面这两条路线。第一个是使用 handle(username) 从 dB 中搜索用户,第二个是使用 dB 本身创建的 user_id 进行搜索。当我使用错误的句柄请求第一条路线时, then() 块被执行并且我得到了这个响应:
{
"noprofile": "There is no profile for this user for handle route (from then block)"
}
但是在第二条路线中(通过 user_id 搜索),当我输入错误 user_id 时,catch 块被执行并且我得到了这个响应:
{
"profile": "There is no profile for this user for user_id route (from error block)",
"err": {
"message": "Cast to ObjectId failed for value \"5cb0ec06d1d6f93c20874427rhdh\" at path \"user\" for model \"profile\"",
"name": "CastError",
"stringValue": "\"5cb0ec06d1d6f93c20874427rhdh\"",
"kind": "ObjectId",
"value": "5cb0ec06d1d6f93c20874427rhdh",
"path": "user"
}
}
两条路线的逻辑相同,但它们正在响应differently.What这背后的原因是什么???
如果您想查看配置文件架构,请在此处查看:
const ProfileSchema = new Schema({
user: {
type: Schema.Types.ObjectId,
ref: 'users'
},
handle: {
type: String,
required: true,
max: 40
},
company: {
type: String
},
....
....
.....
});
我在使用错误句柄请求时也收到警告,如下所示:
(node:16996) UnhandledPromiseRejectionWarning: Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
at ServerResponse.setHeader (_http_outgoing.js:470:11)
at ServerResponse.header (H:\MERN Stack Course\devConnector\node_modules\express\lib\response.js:767:10)
at ServerResponse.send (H:\MERN Stack Course\devConnector\node_modules\express\lib\response.js:170:12)
at ServerResponse.json (H:\MERN Stack Course\devConnector\node_modules\express\lib\response.js:267:15)
at Profile.findOne.populate.then.catch.err (H:\MERN Stack Course\devConnector\routes\api\profile.js:75:39)
at process._tickCallback (internal/process/next_tick.js:68:7)
(node:16996) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:16996) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
我认为在您的第二条路线中,您正在尝试使用无效的 ObjectID 进行查询。
请检查:What's Mongoose error Cast to ObjectId failed for value XXX at path "_id"?
检查错误信息
"message": "Cast to ObjectId failed for value \"5cb0ec06d1d6f93c20874427rhdh\" at path \"user\" for model \"profile\""
user
字段是 mongodb 类型 ObjectId
并且您提供 String
而 handle
是 String
如果 handle
查询没有错误,只是您的 db
.
中没有条目
您可以像 mongoose.Types.ObjectId(req.params.user_id)
一样修复它。 More here
另外,您的代码有问题。 (执行不会在您认为停止的地方停止,并且您会收到未处理的承诺拒绝)
.then(profile => {
//console.log('profile1 ' + profile);
if (!profile) { // <--- if true
errors.noprofile = 'There is no profile for this user for handle route (from then block)';
res.status(404).json(errors); // <-- executes
}
res.json(profile); // <--- always executes within then callback
})
如果此检查 if (!profile)
的计算结果为 true
,则执行 res.status(404).json(errors)
。然后执行下一个res.json(profile)
。
在您的代码中,res.json(profile)
总是在没有错误的情况下执行。您可以通过使用 return
停止执行或 if..else
来纠正:
return res.status(404).json(errors);
// or
if (!profile) {
errors.noprofile = 'There is no profile for this user for handle route (from then block)';
res.status(404).json(errors);
} else {
res.json(profile);
}
// @route GET api/profile/handle/:handle
// @desc Get profile by handle
// @access Public
router.get('/handle/:handle', (req, res) => {
const errors = {};
Profile.findOne({ handle: req.params.handle })
.populate('user', ['name', 'avatar'])
.then(profile => {
//console.log('profile1 ' + profile);
if (!profile) {
errors.noprofile = 'There is no profile for this user for handle route (from then block)';
res.status(404).json(errors);
}
res.json(profile);
})
.catch(err => res.status(404).json({ profile: 'There is no profile for this user for handle route (from error block)' }));
});
// @route GET api/profile/user/:user_id
// @desc Get profile by user ID
// @access Public
router.get('/user/:user_id', (req, res) => {
const errors = {};
Profile.findOne({ user: req.params.user_id })
.populate('user', ['name', 'avatar'])
.then(profile => {
// console.log('profile not found by userid');
//console.log('profile2 ' + profile);
if (!profile) {
errors.noprofile = 'There is no profile for this user for user_id route (from then block)';
res.status(404).json(errors);
}
res.json(profile);
})
.catch(err => res.status(404).json({ profile: 'There is no profile for this user for user_id route (from error block)',
err: err }));
});
我有上面这两条路线。第一个是使用 handle(username) 从 dB 中搜索用户,第二个是使用 dB 本身创建的 user_id 进行搜索。当我使用错误的句柄请求第一条路线时, then() 块被执行并且我得到了这个响应:
{
"noprofile": "There is no profile for this user for handle route (from then block)"
}
但是在第二条路线中(通过 user_id 搜索),当我输入错误 user_id 时,catch 块被执行并且我得到了这个响应:
{
"profile": "There is no profile for this user for user_id route (from error block)",
"err": {
"message": "Cast to ObjectId failed for value \"5cb0ec06d1d6f93c20874427rhdh\" at path \"user\" for model \"profile\"",
"name": "CastError",
"stringValue": "\"5cb0ec06d1d6f93c20874427rhdh\"",
"kind": "ObjectId",
"value": "5cb0ec06d1d6f93c20874427rhdh",
"path": "user"
}
}
两条路线的逻辑相同,但它们正在响应differently.What这背后的原因是什么???
如果您想查看配置文件架构,请在此处查看:
const ProfileSchema = new Schema({
user: {
type: Schema.Types.ObjectId,
ref: 'users'
},
handle: {
type: String,
required: true,
max: 40
},
company: {
type: String
},
....
....
.....
});
我在使用错误句柄请求时也收到警告,如下所示:
(node:16996) UnhandledPromiseRejectionWarning: Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
at ServerResponse.setHeader (_http_outgoing.js:470:11)
at ServerResponse.header (H:\MERN Stack Course\devConnector\node_modules\express\lib\response.js:767:10)
at ServerResponse.send (H:\MERN Stack Course\devConnector\node_modules\express\lib\response.js:170:12)
at ServerResponse.json (H:\MERN Stack Course\devConnector\node_modules\express\lib\response.js:267:15)
at Profile.findOne.populate.then.catch.err (H:\MERN Stack Course\devConnector\routes\api\profile.js:75:39)
at process._tickCallback (internal/process/next_tick.js:68:7)
(node:16996) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:16996) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
我认为在您的第二条路线中,您正在尝试使用无效的 ObjectID 进行查询。
请检查:What's Mongoose error Cast to ObjectId failed for value XXX at path "_id"?
检查错误信息
"message": "Cast to ObjectId failed for value \"5cb0ec06d1d6f93c20874427rhdh\" at path \"user\" for model \"profile\""
user
字段是 mongodb 类型 ObjectId
并且您提供 String
而 handle
是 String
如果 handle
查询没有错误,只是您的 db
.
您可以像 mongoose.Types.ObjectId(req.params.user_id)
一样修复它。 More here
另外,您的代码有问题。 (执行不会在您认为停止的地方停止,并且您会收到未处理的承诺拒绝)
.then(profile => {
//console.log('profile1 ' + profile);
if (!profile) { // <--- if true
errors.noprofile = 'There is no profile for this user for handle route (from then block)';
res.status(404).json(errors); // <-- executes
}
res.json(profile); // <--- always executes within then callback
})
如果此检查 if (!profile)
的计算结果为 true
,则执行 res.status(404).json(errors)
。然后执行下一个res.json(profile)
。
在您的代码中,res.json(profile)
总是在没有错误的情况下执行。您可以通过使用 return
停止执行或 if..else
来纠正:
return res.status(404).json(errors);
// or
if (!profile) {
errors.noprofile = 'There is no profile for this user for handle route (from then block)';
res.status(404).json(errors);
} else {
res.json(profile);
}