web-dev-qa-db-fra.com

Messages d'erreur personnalisés avec Mongoose

Donc, selon mongoose docs , vous êtes censé être capable de définir un message d’erreur personnalisé dans le schéma, comme ceci:

 var breakfastSchema = new Schema({
  eggs: {
    type: Number,
    min: [6, 'Too few eggs'],
    max: 12
  },
  bacon: {
    type: Number,
    required: [true, 'Why no bacon?']
  }
});

Alors je voulais faire quelque chose de similaire:

var emailVerificationTokenSchema = mongoose.Schema({
   email: {type: String, required: true, unique: [true, "email must be unique"]},
   token: {type: String, required: true},
   createdAt: {type: Date, required: true, default: Date.now, expires: '4h'}
});

L'idée étant que lorsque vous essayez de sauvegarder l'un de ces jetons, et qu'il y en a déjà un en conflit, un message d'erreur indiquant que "le courrier électronique doit être unique" doit s'afficher.

Cependant, quand je fais quelque chose comme ça (où je sauve un jeton avec le même email):

verificationToken.save( function (err) {
    if (err) {
      return console.log(err);
    }
    else {
      return console.log(err);
    }
});

Je continue à avoir ceci:

'E11000 duplicate key error: index ___.emailVerificationToken.$email_1 dup key: { : "[email protected]

Des pensées? Le paramètre unique n'est-il pas pris en charge pour les messages personnalisés? Est-ce une manière viable de faire les choses?

11
Vangogh500

Le paramètre unique n'est-il pas pris en charge pour les messages personnalisés?

L'unicité dans Mongoose n'est pas un paramètre de validation (comme required); il demande à Mongoose de créer un index unique dans MongoDB pour ce champ.

La contrainte d'unicité est entièrement gérée sur le serveur MongoDB. Lorsque vous ajoutez un document avec une clé en double, le serveur MongoDB renvoie l'erreur que vous affichez (E11000...).

Vous devez gérer ces erreurs vous-même si vous souhaitez créer des messages d'erreur personnalisés. La documentation Mongoose (recherche "Erreur de gestion du middleware") fournit un exemple de création d'un traitement d'erreur personnalisé:

emailVerificationTokenSchema.post('save', function(error, doc, next) {
  if (error.name === 'MongoError' && error.code === 11000) {
    next(new Error('email must be unique'));
  } else {
    next(error);
  }
});

(bien que cela ne vous fournisse pas le champ spécifique pour lequel la contrainte d'unicité a échoué)

13
robertklep

Ce n'est pas directement possible car vous l'avez essayé, mais vous voudrez peut-être jeter un œil à mongoose-unique-validator , qui permet de créer un message d'erreur personnalisé si l'unicité est violée. 

En particulier, la section sur custom errors devrait vous intéresser. 

Pour obtenir votre désir 

"l'email doit être unique" 

ça ressemblerait à ça 

var uniqueValidator = require('mongoose-unique-validator');
...
emailVerificationTokenSchema.plugin(uniqueValidator, { message: '{PATH} must be unique' });
4
DAXaholic
verificationToken.save( function (err) {
    if (err) {
      return res.status(400).send({
          message: (err.name === 'MongoError' && err.code === 11000) ? 'Email already exists !' : errorHandler.getErrorMessage(err)
      });
    }
    else {
      return console.log('No Error');
    }
  });
1
Gautam

Version mise à jour pour Mongoose 5.x.x

MySchema.post('save', function (error, doc, next) {
    if (err.name === 'BulkWriteError' && error.code === 11000) 
        next(new Error('This item already exists, please try again'));
    else next(error);
});
0
ThunderRoid