Node.js 多次设置自定义验证错误

Node.js 多次设置自定义验证错误,node.js,loopbackjs,strongloop,Node.js,Loopbackjs,Strongloop,我通过以下方式为我的一个模型属性创建了自定义验证: Model.validateAsync('minOsVersion', validateMinimumOsVersion, {message: 'Minimum OS Version incorrect'}); function validateMinimumOsVersion(err, done) { var requiredVersion = "some version"; var givenVersion = this.m

我通过以下方式为我的一个模型属性创建了自定义验证:

Model.validateAsync('minOsVersion', validateMinimumOsVersion, {message: 'Minimum OS Version incorrect'});
function validateMinimumOsVersion(err, done) {
    var requiredVersion = "some version";
    var givenVersion = this.minOsVersion;
    if (validator.validateSemanticVersionString(givenVersion, requiredVersion) < 0) {
      err('too_low');
    }
    done();
  }

上传时更新属性但不多次生成验证的更好方法是什么?正如我在评论中提到的,出现多个验证错误的原因是多次调用
updateAttribute()
。相反,考虑使用只应调用验证方法一次:


还要注意,我添加了用于更新属性的回调。这是一个异步函数,实际上执行更新,因此您需要在完成后执行
cb()
回调。

upload
端点做什么?看起来您要命中的端点不是标准(生成的)模型端点,因此我猜测可能有某个循环多次命中模型,从而生成多个错误。我想我们需要看看端点代码才能确定。是的,你完全正确。在safe挂钩之前,我在
中对对象执行一些
updateAttribute
调用。我正在这个端点上传一个文件,取消其大小并提取一些元信息,然后在http请求返回之前使用
updateArribute
更新这些元信息(并最终返回元数据检查的验证)。@jakerella我添加了一些缺少的代码谢谢@jakerella,这修复了它。还感谢您的异步注释。
Model.observe('before save', function(ctx, next) {
    if (ctx.instance) {
      analyseMetadata(ctx.instance, function(error, model) {
        if (error) { return next(error); }
        next();
      });
    } else {
      next();
    }
  });

  function analyseMetadata(model, cb) {
    extractMetadata(model, function(error, data){
      if (error) { return cb(error); }

      if (data && data.provisioning && data.metadata && data.entitlements) {
        model.updateAttribute("expires", data.provisioning.ExpirationDate);
        model.updateAttribute("created", data.provisioning.CreationDate);

        model.updateAttribute("appIdentifier", data.entitlements['application-identifier']);
        model.updateAttribute("teamIdentifier", data.entitlements['com.apple.developer.team-identifier']);

        model.updateAttribute("bundleIdentifier", data.metadata.CFBundleIdentifier);
        model.updateAttribute("displayName", data.metadata.CFBundleDisplayName);
        model.updateAttribute("bundleName", data.metadata.CFBundleName);
        model.updateAttribute("shortVersion", data.metadata.CFBundleShortVersionString);
        model.updateAttribute("bundleVersion", data.metadata.CFBundleVersion);
        model.updateAttribute("minOsVersion", data.metadata.MinimumOSVersion);
        model.updateAttribute("builtOsVersion", data.metadata.DTPlatformVersion);
      }
      cb(null, model);
    });
  }
function analyseMetadata(model, cb) {
  extractMetadata(model, function(error, data){
    if (error) { return cb(error); }

    if (data && data.provisioning && data.metadata && data.entitlements) {
      model.updateAttributes({
        "expires": data.provisioning.ExpirationDate,
        "created": data.provisioning.CreationDate,
        "appIdentifier": data.entitlements['application-identifier'],
        // ...
      }, function updateCallback(updateErr, updatedModel) {
        if (updateErr) { return cb(updateErr); }

        cb(null, updatedModel);
      });
    }
  });
}