2017-10-20 46 views
1

J'essaie de refactoriser un code API simple basé sur Express pour utiliser des promesses au lieu de rappels. Mon seul défi est de gérer les erreurs de validation de Mongoose (exemple de test si l'utilisateur existe) et de lancer cette erreur dans le middleware.Erreur de validation du handle de mangouste dans un appel de promesse et middleware express

Je gestion des erreurs par un middleware sur index.js:

// Error handling middleware 
app.use(function(err, req, res, next){ 
    res.status(422).send({error: err._message}) 
}); 

C'est le morceau de code qui gère avec succès tous les cas de pointe à l'exception de la partie existingUser où l'erreur est jeté dans l'oubli et non visible dans la réponse:

router.post('/signup', function(req, res, next) { 
    const email = req.body.email; 
    const password = req.body.password; 

    // Custom error 
    if (!email || !password) { 
    return res.status(422).send({ error: 'You must provide email and password'}); 
    } 

    User.findOne({ email: email }) 
    .then(function(existingUser) { 
    // If a user with email does exist, return an error 
    if (existingUser) { 
     // return res.status(422).send({ error: 'Email is in use' }); 
     throw new Error('User already exists!'); 
    } 

    // If a user with email does NOT exist, create and save user record 
    const user = new User({ 
     email: email, 
     password: password 
    }); 

    // save to database 
    return user.save() 
    }) 
    .then(function(user) { 
    // Respond to request indicating the user was created 
    res.json({ token: tokenForUser(user) }); 
    }) 
    .catch(next); 

Remarque que je commentais ce morceau de code parce qu'il renvoie une erreur « Impossible de définir les en-têtes après leur envoi »:

return res.status(422).send({ error: 'Email is in use' }); 

Mes questions sont les suivantes:

  1. est la façon dont je gère les erreurs de validation personnalisée (comme les tests si les champs e-mail ou mot de passe sont vides) correcte, ou il y a de meilleures façons, puisque je ne suis pas les transmettre à travers le middleware d'erreur?
  2. Comment gérer les erreurs dans les promesses?

Répondre

1

Vous pouvez tester le nom d'utilisateur et mot de passe dans une nouvelle promesse:

Promise.resolve().then(()=> { 
    if (!email || !password) { 
    throw new Error('You must provide email and password'); 
    } 
    return User.findOne({ email: email }) 
}) 

Lancer une erreur dans la fonction then arrêtera l'exécution et appeler le premier catch attaché à la promesse. Dans votre cas, le rappel next avec comme premier argument l'erreur trowed. Imo, vous vous débrouillez bien, c'est à l'application expresse d'envoyer l'erreur du client de manière appropriée dans le bon middleware.

+0

Pour clarifier la deuxième question, je dois valider la partie "if (existingUser)". –

+0

J'ai mis à jour ma réponse, je suppose que cela répond à votre question;) – jsan