34

ユーザーモデルには 2 つの検証関数があります

User.schema.path('email').validate(function(value, respond) {
  User.findOne({email: value}, function(err, user) {
    if(err) throw err;
    if(user) return respond(false);
    respond(true);
  });
}, 'EMAIL_EXISTS');

そして同じusername

User.schema.path('username').validate(function(value, respond) {
  User.findOne({username: value}, function(err, user) {
    if(err) throw err;
    if(user) return respond(false);
    respond(true);
  });
}, 'USERNAME_TAKEN');

次の形式でエラーを返します

{ message: 'Validation failed',
  name: 'ValidationError',
  errors: 
    { username: 
      { message: 'Validator "USERNAME_TAKEN" failed for path username',
        name: 'ValidatorError',
        path: 'username',
        type: 'USERNAME_TAKEN' } } }

emailパスのエラーも同様です。これらのエラーをチェックするよりスマートな方法はありますか?

if (err && err.errors && err.errors.username) { ... }

これはちょっと醜いです。

4

8 に答える 8

34

技術的には、すべてのエラーが同じ方法で処理されるわけではないため、最初にエラー名を確認する必要があります。次に、エラー名に基づいて、ValidationError に付属するエラー プロパティとして、特定のプロパティをチェックする必要があります。

また、フィールド名をエラー タイプに入れますが、これは冗長です。エラー チェック手順でフィールド名も取得するため、同じエラー タイプを使用することをお勧めします。

したがって、コードは次のようになります。

User.schema.path('email').validate(function(value, respond) {
  User.findOne({email: value}, function(err, user) {
    if(err) throw err;
    if(user) return respond(false);
    respond(true);
  });
}, 'exists');

User.schema.path('username').validate(function(value, respond) {
  User.findOne({username: value}, function(err, user) {
    if(err) throw err;
    if(user) return respond(false);
    respond(true);
  });
}, 'exists');

そして、エラーチェック手順:

if (err) {
  switch (err) {
    case err instanceof mongoose.Error.ValidationError:
      for (field in err.errors) {
        switch (err.errors[field].type) {
          case 'exists':
            ...
            break;
          case 'invalid':
            ...
            break;
          ...
        }
      }
      break;
    default:
      ...
  }
}

これを短縮したい場合は、さまざまなオプションがあります。検証のタイプが 1 つしかない場合は、次のように実行できます。

if (err) {
  if (err instanceof mongoose.Error.ValidationError) {
    for (field in err.errors) {
      ...
    }
  } else {
    // A general error (db, crypto, etc…)
    ...
  }
}

エラーチェック手順の最小限の表現は、投稿に書いたものと似ています:

if (err) {
  for (field in err.errors) {
    ...
  }
}

エラーが定義されていない場合は for が無視されるため、これは機能します。ただし、ここでは他のすべてのエラー タイプを無視しています。

また、これらのエラー レイアウトは少しごちゃごちゃしていると思いますが、これが近い将来変更されるとは思わないでください。

于 2013-02-01T08:23:30.760 に答える
10

次のコードを書いて楽しんでください。

if (err) {
    console.log('Error Inserting New Data');
    if (err.name == 'ValidationError') {
        for (field in err.errors) {
            console.log(err.errors[field].message); 
        }
    }
}
于 2015-06-29T14:18:11.417 に答える
3

私は AngularJS を使用しているためngRepeat、Web フォームに検証エラーが表示されます。エラー メッセージの配列を返すだけです。

Mongoose は、検証エラーではないエラーをスローすることがあります。この場合、err.errors オブジェクトは存在しません。実行エラーを記録します。私はまだ Web フォームの同じ場所を使用して、実行エラーをユーザーに表示しています。

var makeMongooseErrorMsgArray = function(err){
    var msgArray = [];
    if (err.errors) { // validation errors
        $.each(err.errors, function (key, val) {
            msgArray.push(val.message);
        });
    } else if (err.message){ // should be execution error without err.errors
        errLogr.log(err); // log execution errors
        msgArray.push(err.message);
    } else {
        msgArray.push('Unknown error');
    }
    return msgArray;
}
于 2016-03-14T14:36:14.717 に答える
2

配列内のすべてのエラーを表示するこれが役立つことがわかりました。

たとえば、短いパスワードと無効な電子メールを含むフォームを送信しました。

if (err && err.name === 'ValidationError') {
   err.toString().replace('ValidationError: ', '').split(',')
}

これは

[ 'Please provide a valid email address',
'The password should be at least 6 characters long' ]

,エラーメッセージにコンマがある場合は、なしで試してください.split(',')

forループは必要ありません。スキーマに検証エラー メッセージがあることを確認してください。上記の例では、

const validateEmail = email => {
  const re = /^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/;
  return re.test(email);
};

const Schema = mongoose.Schema;
const userSchema = new Schema({
   ...
   email: {
      type: String,
      trim: true,
      required: 'Email address is required',
      validate: [validateEmail, 'Please provide a valid email address'],
   },
   password: { type: String, set: encryptPassword, maxlength: [6, 'The password should be at least {MAXLENGTH} characters long'] },
   ...
});
于 2015-11-15T01:58:01.847 に答える
0

APIで説明されてvalidationいるメソッドを使用してみませんか?

objectToSave.validate(function(err) {          
  if (err) {
    // handle error
  }     
  else {
    // validation passed
  }
});
于 2013-01-31T00:56:06.953 に答える