Reputation: 3274
i was following some react/express tutorials. im confused with code below in contacts.js file
if (!contact) {
return res.status(404).json({ msg: "Contact not found" })
}
Is above code necessary ? or whats is there better way to catch if the contact doesn't exist in mongodb ?
when i do put request from postman with invalid id for example
localhost:44022/api/contacts/<invalid ID>
the execution never reach if (!contact) part. if i console log the catch(err) section i get something below
CastError: Cast to ObjectId failed for value "bcvbxcxc" at path "_id" for model "contact"
at model.Query.exec (/Users/becker/Desktop/RJS/ckeeper/node_modules/mongoose/lib/query.js:4380:21)
at model.Query.Query.then (/Users/becker/Desktop/RJS/ckeeper/node_modules/mongoose/lib/query.js:4472:15)
at runMicrotasks (<anonymous>)
at processTicksAndRejections (internal/process/task_queues.js:97:5) {
messageFormat: undefined,
stringValue: '"bcvbxcxc"',
kind: 'ObjectId',
value: 'bcvbxcxc',
path: '_id',
reason: Error: Argument passed in must be a single String of 12 bytes or a string of 24 hex characters
at new ObjectID (/Users/becker/Desktop/RJS/ckeeper/node_modules/bson/lib/bson/objectid.js:59:11)
contacts.js
router.put('/:id', auth, async (req, res) => {
const { name, email, phone, type } = req.body;
const contactFields = {};
if (name) contactFields.name = name;
if (email) contactFields.email = email;
if (phone) contactFields.phone = phone
if (type) contactFields.type = type;
try {
let contact = await Contact.findById(req.params.id);
if (!contact) {
return res.status(404).json({ msg: "Contact not found" })
}
//makesure contact belongs to right user
if (contact.user.toString() != req.user.id) {
return res.status(401).json({ msg: 'Not authorized' })
}
contact = await Contact.findByIdAndUpdate(req.params.id, { $set: contactFields }, { new: true })
res.json(contact)
}
catch (err) {
console.log("reached error, contact not found")
console.error(err)
res.status(500).send(err)
}
});
Contacts.js model
const mongoose = require('mongoose');
const ContactSchema = mongoose.Schema({
user: {
type: mongoose.Schema.Types.ObjectId,
ref: 'users'
},
name: {
type: String,
required: true
},
email: {
type: String,
required: true,
},
phone: {
type: String
},
type: {
type: String,
default: 'personal'
},
date: {
type: Date,
default: Date.now
}
});
module.exports = mongoose.model('contact', ContactSchema)
Upvotes: 0
Views: 78
Reputation: 4302
The reason for not executing the if(!contact)
condition upon exception is because catch
block will be called and further execution in the try block is halted. You should rather wrap each db
call in its own try catch
block. Something like:
let contact;
try {
contact = await Contact.findById(req.params.id);
} catch(err) {
console.log('Some db operations failed due to reason', err);
return res.status(500).json({ msg: "DB operations failed or whatever message" })
}
if (!contact) {
return res.status(404).json({ msg: "Contact not found" })
}
//makesure contact belongs to right user
if (contact.user.toString() != req.user.id) {
return res.status(401).json({ msg: 'Not authorized' })
}
try {
contact = await Contact.findByIdAndUpdate(req.params.id, { $set: contactFields }, { new: true })
return res.json(contact)
}
catch (err) {
console.log("db update operations failed")
console.error(err)
res.status(500).send(err)
}
Upvotes: 1