I am creating a mongoose static method 'load' so that my main controller function can use it (for chainning and error handling).
UserSchema.load('54ae92dd8b8eef540eb3a66d')
.then(....)
.catch(....);
The thing is the id is something wrong so I need to catch this error. and I am thinking it is better to do this in the model layer.
When I do the following the controller can catch this error.
UserSchema.statics.load = function(id) {
if (!mongoose.Types.ObjectId.isValid(id)) {
return Promise.resolve().then(function() {
throw new Error('not a mongoose id');
}); ------------( * )
}
return Promise.cast(this.findOne({
_id: id
}).exec());
};
But if I only do the following the error is not successfully thrown into the controller .catch function.
AchievementSchema.statics.load = function(id) {
if (!mongoose.Types.ObjectId.isValid(id)) {
throw new Error('not a mongoose id');
}
return Promise.cast(this.findOne({
_id: id
}).exec());
};
so my question is am I doing this correctly? If so is there easier ways to write the (*) statement? What I am doing seems ugly.. Thanks.
Yes, there is a shorthand called Promise.reject
.
Your code in:
if (!mongoose.Types.ObjectId.isValid(id)) {
return Promise.resolve().then(function() {
throw new Error('not a mongoose id');
}); ------------( * )
}
Can be written as:
return Promise.reject(new Error("Not a mongoose id");
You can do even better though, Promise.method
exists to ensure anything that might return a promise will return a promise:
UserSchema.statics.load = Promise.method(function(id) {
if (!mongoose.Types.ObjectId.isValid(id)) {
throw new Error('not a mongoose id: ' + id);
}
return this.findOne({ _id: id }).exec());
});
This will both case the findOne
result to a Bluebird trusted promise and convert the throw
to a rejection for you. You might want to consider throwing a subclass of Promise.OperationalError
rather than Error
though.
As an unrelated tip Promise.cast
was deprecated in favor of Promise.resolve
over a year ago.