web-dev-qa-db-fra.com

La validation Joi ne renvoie qu'un seul message d'erreur

J'ai un formulaire à trois champs composé d'un champ de nom, d'un champ de courrier électronique et d'une zone de texte. J'utilise la version Joi 4.7.0 avec des hapijs. J'utilise l'objet ci-dessous pour valider l'entrée. Je reçois l'objet de données d'un appel ajax. Lorsque je remplis les trois champs avec des informations erronées, je ne reçois que le message relatif au premier champ erroné. Comme ça:

"{"statusCode":400,"error":"Bad Request","message":"name is not allowed to be empty","validation":    {"source":"payload","keys":["data.name"]}}"

validate: {
      payload: {
        data: {
          name: Joi.string().min(3).max(20).required(),
          email: Joi.string().email().required(),
          message: Joi.string().min(3).max(1000).required()
        }
      }
}

Pour explication, supposons de ne pas remplir les trois champs. Je reçois une seule erreur de message et non l'erreur de message des autres champs. Pourquoi?

26
Mazzy

Cela se produit parce que Joi abandonne tôt par défaut.

abortEarly - lorsque true, arrête la validation sur la première erreur, sinon renvoie toutes les erreurs trouvées. Par défaut, true.

* EDIT: La configuration a changé dans hapi 8.0. Vous devez ajouter abortEarly: false à la configuration routes:

var server = new Hapi.Server();
server.connection({
    Host: 'localhost',
    port: 8000,
    routes: {
        validate: {
            options: {
                abortEarly: false
            }
        }
    }
});

* Voir la documentation de l'API Joi pour plus de détails.
* Voir aussi validation sous Options Hapi Route .

Joi arrête donc la validation sur la première erreur:

var Hapi = require('hapi');
var Joi = require('joi');

var server = new Hapi.Server('localhost', 8000);

server.route({
    method: 'GET',
    path: '/{first}/{second}',
    config: {
        validate: {
            params: {
                first: Joi.string().max(5),
                second: Joi.string().max(5)
            }
        }
    },
    handler: function (request, reply) {

        reply('example');
    }
});

server.start();

server.inject('/invalid/invalid', function (res) {

    console.log(res.result);
});

Les sorties:

{ statusCode: 400,
  error: 'Bad Request',
  message: 'first length must be less than or equal to 5 characters long',
  validation: { source: 'params', keys: [ 'first' ] } }

Vous pouvez cependant configurer Hapi pour renvoyer toutes les erreurs. Pour cela, vous devez définir abortEarly sur false. Vous pouvez le faire dans la configuration du serveur:

var server = new Hapi.Server('localhost', 8000, { validation: { abortEarly: false } });

Si vous exécutez le script maintenant, vous obtenez:

{ statusCode: 400,
  error: 'Bad Request',
  message: 'first length must be less than or equal to 5 characters long. second length must be less than or equal to 5 characters long',
  validation: { source: 'params', keys: [ 'first', 'second' ] } }
28
Gergo Erdosi

Je n'intègre pas hapi.js, mais j'ai remarqué qu'il existe un objet ValidationOptions qui peut être transmis. À l'intérieur de cet objet se trouve une option abortEarly, donc cela devrait fonctionner:

Joi.validate(request, schema, { abortEarly: false }

Cela peut également être configuré comme suit:

Joi.object().options({ abortEarly: false }).keys({...});

Consultez ces définitions de type pour plus de ValidationOptions: https://github.com/DefinitelyTyped/tsd/blob/master/typings/joi/joi.d.ts

13
Stephen Paul

La touche validation ne fonctionne plus avec le Hapi.Server constructeur dans Hapi 8.0:

[1] la validation n'est pas autorisée

J'ai trouvé la solution dans un problème GitHub pour hapi :

var Hapi = require('hapi');


var server = new Hapi.Server();

server.connection({
  Host: Host,
  port: PORT,
  routes: {
    validate: {
      options: {
        abortEarly: false
      }
    }
  }
});

// Route using Joi goes here.
server.route({});

server.start(function () {
  console.log('Listening on %s', server.info.uri);
});
4
chris van