58

Mongoose で検証エラーを処理する方法を決定しようとしています。

node-validator を使用したカスタム エラー メッセージ

node-validatorを使用して独自の検証ルールを定義しました。次に例を示します。

UserSchema.path('username')
  .validate(function (username) {
    return validator.check(username).notEmpty()
  }, 'Username cannot be blank')

次のようなエラーが生成されます。

  username: 
   { message: 'Validator "Username cannot be blank" failed for path username',
     name: 'ValidatorError',
     path: 'username',
     type: 'Username cannot be blank' },

マングースバリデーターの使用

ただし、node-validator は独自のエラー メッセージを提供します。mongoose-validator Node モジュールを使用してnode-validator をスキーマに直接プラグインする場合、代わりにこれらのエラー メッセージを直接使用できます。

var UserSchema = new Schema({
  name: { type: String, validate: [validate('notEmpty')] }
});

次のようなエラー メッセージが生成されます。

  name: 
   { message: 'Validator "String is empty" failed for path name',
     name: 'ValidatorError',
     path: 'name',
     type: 'String is empty' } }

ここでもカスタム エラー メッセージを提供できます。

var UserSchema = new Schema({
  name: { type: String, validate: [validate({message: 'Name cannot be blank' }, 'notEmpty')] }
});

マングースrequiredの旗

Mongoose では、必要に応じてフィールドを定義できます。

var UserSchema = new Schema({
  name: { type: String, required: true }
});

次のようなエラー メッセージが生成されます。

  name: 
   { message: 'Validator "required" failed for path name',
     name: 'ValidatorError',
     path: 'name',
     type: 'required' } }

質問

これらのバリデーターは、組み込みのエラー メッセージを使用することを望んでいるように感じます。たとえば、required上記のようにフィールドを宣言したいのですが、エラー メッセージをカスタマイズする方法が見つかりません。また、mongoose-validator モジュールはごく最近までカスタム メッセージをサポートしていませんでした。これは、モデル レベルでのアンチパターンであると私に思わせます。

これらのバリデーターを実装する最良の方法は何ですか? 独自のエラーを生成させてから、何らかの方法で後で解釈する必要がありますか?

4

9 に答える 9

36

この時点で、マングースがエラーを処理する方法を理解するのは理にかなっているように思えます。

モデルでエラー メッセージを処理したくない場合。プレゼンテーション層 (コントローラー?) は、表示するのに最適なユーザーフレンドリーなメッセージを決定するために、に依存する必要typeがあります (i18n を考慮)。

ミドルウェアを使用して検証が行われる場合もあります。この場合、コントローラに表示されるエラー メッセージは、next()コールバックに渡すものです。

したがって、ミドルウェアの場合、文書化されていませんが、モデル全体で一貫した検証 API を維持するには、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();
});

そうすれば、検証エラーがミドルウェアに起因する場合でも、一貫した検証エラー処理が保証されます。

エラー メッセージを型に適切に一致させるには、考えられるすべての型の静的マップとして機能する列挙型を作成します。

// 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);

    }
  });
});
于 2013-06-10T12:43:33.273 に答える
22

バリデータ プラグインがおそらく役立つことはわかっていますが、マングースのバリデーションは実際には複雑というよりも威圧的だと思います。見た目は確かに複雑そうに見えますが、いじってみるとそれほど悪くはありません。

以下のコードを確認すると、組み込みのバリデータを使用してカスタム エラー メッセージを返す方法の例を確認できます。

フィールドを設定するときに、独自のカスタム エラー メッセージで 2 番目のパラメーターを設定するだけです。

required以下のandフィールドminlengthとフィールドをチェックmaxlengthして、カスタム エラー メッセージをどのように設定したかを確認してから、エラー オブジェクトにアクセスする方法やフロント エンドに送信する方法について、以下のメソッドをチェックしてください。

// Grab dependencies:
var mongoose = require('mongoose');

// Setup a schema:
var UserSchema = new mongoose.Schema (
    {
        username: {
            type: String,
            minlength: [2, 'Username must be at least 2 characters.'],
            maxlength: [20, 'Username must be less than 20 characters.'],
            required: [true, 'Your username cannot be blank.'],
            trim: true,
            unique: true,
            dropDups: true,
        }, // end username field
    },
    {
        timestamps: true,
    },
);

// Export the schema:
module.exports = mongoose.model('User', UserSchema);

上記は、カスタム エラー メッセージを持つようにフィールドを設定します。しかし、どうやってそれらにアクセスしたり、フロントエンドに送信したりするのでしょうか? サーバー コントローラーで次のメソッドをセットアップし、その応答データを angular に送り返すことができます。

var myControllerMethods = {
    register : function(req, res) {
        // Create a user based on the schema we created:
        User.create(req.body)
            .then(function(newUser) {
                console.log('New User Created!', newUser);
                res.json(newUser);
            })
            .catch(function(err) {
                if (err.name == 'ValidationError') {
                    console.error('Error Validating!', err);
                    res.status(422).json(err);
                } else {
                    console.error(err);
                    res.status(500).json(err);
                }
            })
    },
};

上記のコードを実行し、いずれかのマングース バリデーターがパスしなかった場合、エラー ( err) オブジェクトが.catch()promise によって取得されます。このエラーをコンソールに記録すると、フラグが立てられたエラーに応じて、そのオブジェクトにカスタム メッセージが表示されます。

注: 上記の例は、Mongoose が所有する組み込みの検証 ( 、 など) にカスタム検証メッセージを追加するためのrequiredものminlengthですmaxlength

正規表現パターンなどに対するフィールドの検証など、より高度な検証を作成する場合は、カスタムvalidator関数を作成する必要があります。

フィールドにバリデータを追加する方法の良い例については、このリンクの「カスタム バリデータ」セクションを参照してください: http://mongoosejs.com/docs/validation.html

注:「事前保存フック」と「インスタンスメソッド」を使用することもできますが、これはこの質問の範囲を超えており、組み込みのバリデーターと「カスタムバリデーター」(前述のリンク)はより簡単なルートです。

お役に立てれば!

于 2017-01-31T10:23:56.257 に答える
4

マングースから: https://github.com/leepowellcouk/mongoose-validator

エラー メッセージ カスタム エラー メッセージは 0.2.1 で復活し、オプション オブジェクトを介して設定できます。

validate({message: "String should be between 3 and 50 characters"}, 'len', 3, 50)


これをどのように実装したか:

var emailValidator = [validate({message: "Email Address should be between 5 and 64 characters"},'len', 5, 64), validate({message: "Email Address is not correct"},'isEmail')];

var XXXX = new Schema({
email : {type: String, required: true, validate: emailValidator} }); 

私のフロントエンドはrequiredを扱っているので、マングースの「required」エラーがユーザーに届くとは思っていません。バックエンドのセーフガードです。

于 2013-04-07T13:36:14.210 に答える
2

警告: Mongoose 4.1.3 以降、関数 ValidatorError の署名が完全に変更されたため、以下の情報は適用されなくなりました。

Mongoose 3.8.12 の時点で、関数 ValidatorError のシグネチャは次のとおりです。

function ValidatorError (path, msg, type, val) 

type は「notvalid」または「required」のいずれかです

たとえば、「メール」フィールドの検証で検証エラーが発生した場合は、次のように簡単に実行できます。

var error = new ValidationError(this);
error.errors.email = 
      new ValidatorError('email', "Your err message.", 'notvalid', this.email);
于 2014-11-04T10:57:00.627 に答える
2

一意のインデックス エラーを含む、mongoose エラー メッセージ テンプレートをカスタマイズするのに役立つhmvパッケージを参照してください。

template : {PATH_NAME} must be at least {MIN_LENGTH} characters long
schema   : { fullname : { type : String, min : 3, $name : 'Full name' } }
message  : Full name must be at least 3 characters long

template : {PATH_NAME} {VALUE} have been used, please choose another
schema   : { username : { type : String, unique : true } }
message  : username MrBean have been used, please choose another

また、ベトナム語などのローカリゼーションを具体的にサポートしています。

template : {PATH_NAME} dài ít nhất {MIN_LENGTH} kí tự
schema   : { fullname : { type : String, min : 3, $name : 'tên tài khoản' } }
message  : Tên tài khoản dài ít nhất 5 kí tự

良い点は、前のアプローチですべてのスキーマのすべてのフィールドをカスタマイズするのではなく、メッセージ テンプレートを一度カスタマイズするだけでよいことです。

于 2018-12-16T06:33:57.163 に答える