最好的方法来包装mongoosevalidation错误

我们知道mongoose为我们提供了一个简单的方法来进行validation。 但是,假设你使用express + mongoose来构build一个微服务; 和一些客户端(可能是networking应用程序,手机应用程序等)需要消耗它。

通常,我更喜欢用简单的错误代码和消息来回应JSON。 在大多数情况下,客户可以根据他们向用户显示哪种语言来创build自己的消息。

默认情况下,如果我们从mongoose捕获错误,我们可以得到JSON响应,如:

JSON响应

{ "errors": { "price": { "message": "Path `price` (-1) is less than minimum allowed value (0).", "name": "ValidatorError", "properties": { "min": 0, "type": "min", "message": "Path `{PATH}` ({VALUE}) is less than minimum allowed value (0).", "path": "price", "value": -1 }, "kind": "min", "path": "price", "value": -1, "$isValidatorError": true }, "code": { "message": "Product with given code already exists", "name": "ValidatorError", "properties": { "type": "user defined", "message": "Product with given code already exists", "path": "code", "value": "p-1000" }, "kind": "user defined", "path": "code", "value": "p-1000", "$isValidatorError": true } }, "_message": "Product validation failed", "message": "Product validation failed: price: Path `price` (-1) is less than minimum allowed value (0)., code: Product with given code already exists", "name": "ValidationError" } 

Restful Api控制器

 exports.createOne = async(function* list(req, res) { try { const product = new Product(req.body) const newProduct = yield product.save() res.json(newProduct) } catch (err) { res.status(400).json(err) } }) 

Model.js

 const mongoose = require('mongoose') const Schama = mongoose.Schema const minlength = [5, 'The value of `{PATH}` (`{VALUE}`) is shorter than the minimum allowed length ({MINLENGTH}).']; const ProductSchema = new Schama({ code: { type: String, required: true, minlength, index: true, unique: true, trim: true, lowercase: true }, name: { type: String, required: true, trim: true }, price: { type: Number, required: true, min: 0, max: 100000 }, categories: [String], }) ProductSchema.path('code').validate(function uniqueEmail(code, fn) { const Product = mongoose.model('Product') // Check only when it is a new Product or when code field is modified if (this.isNew || this.isModified('code')) { Product.find({ code }).exec((err, products) => { fn(!err && products.length === 0) }) } else fn(true) }, 'Product with given code already exists') ProductSchema.statics = { /** * List products * * @param {Object} options * @api private */ pageList: function pageList(conditions, index, size) { const criteria = conditions || {} const page = index || 0 const limit = size || 30 return this.find(criteria) .populate('user', 'name username') .sort({ createdAt: -1 }) .limit(limit) .skip(limit * page) .exec() }, } mongoose.model('Product', ProductSchema) 

我期望的

我试图包装错误消息,以便消费者简单。 可能是这样的:

 { "errors": [ { "message": "Path `price` (-1) is less than minimum allowed value (0).", "code": "100020" }, { "message": "Product with given code already exists", "code": "100021" } ], "success": false } 

代码和相应的消息将保存在api文档上。 该消息通常对于消费者理解代码和消费者(例如web客户端)可以根据代码创build他们自己的消息(例如法语消息)并向最终用户显示。

我怎样才能利用mongoose的屈服来完成呢? 也许我可以循环erros的属性,并使用${path}-${kind}组合代码。

我知道在大多数情况下,客户端应该在调用apis之前进行validation。 但是必须有一些API必须抛出错误的情况。

任何想法呢?