A questo punto sembra logico accettare il modo in cui Mongoose gestisce gli errori.
Non vorresti che i tuoi modelli gestissero i messaggi di errore. Il livello di presentazione (controller?) dovrebbe basarsi sul type
per decidere quale sia il miglior messaggio user-friendly da visualizzare (considerato i18n).
C'è anche il caso in cui la convalida può avvenire utilizzando un middleware. In questo caso, il messaggio di errore che apparirà sul tuo controller è qualunque cosa tu passi a next()
richiamata.
Quindi, per il caso del middleware, sebbene non documentato, per mantenere un'API di convalida coerente tra i tuoi modelli dovresti utilizzare direttamente i costruttori di errore di Mongoose:
var mongoose = require('mongoose');
var ValidationError = mongoose.Error.ValidationError;
var ValidatorError = mongoose.Error.ValidatorError;
schema.pre('save', function (next) {
if (/someregex/i.test(this.email)) {
var error = new ValidationError(this);
error.errors.email = new ValidatorError('email', 'Email is not valid', 'notvalid', this.email);
return next(error);
}
next();
});
In questo modo ti viene garantita una gestione coerente degli errori di convalida anche se l'errore di convalida proviene da un middleware.
Per abbinare correttamente i messaggi di errore ai tipi, creerei un enum che fungerebbe da mappa statica per tutti i tipi possibili:
// my controller.js
var ValidationErrors = {
REQUIRED: 'required',
NOTVALID: 'notvalid',
/* ... */
};
app.post('/register', function(req, res){
var user = new userModel.Model(req.body);
user.save(function(err){
if (err) {
var errMessage = '';
// go through all the errors...
for (var errName in err.errors) {
switch(err.errors[errName].type) {
case ValidationErrors.REQUIRED:
errMessage = i18n('Field is required');
break;
case ValidationErrors.NOTVALID:
errMessage = i18n('Field is not valid');
break;
}
}
res.send(errMessage);
}
});
});