2012-11-27 35 views
19

Theo dõi từ: Mongoose unique validation error typeMongoose pre.save() async middleware không làm việc như mong đợi

Tôi đang sử dụng sơ đồ này với mongoose 3.0.3 từ NPM:

var schema = new Schema({ 

    _id: Schema.ObjectId, 
    email: {type: String, required: true, unique: true} 

}); 

Với middleware này để có được một validationError từ unique: true

schema.pre("save", function(next, done) { 
    var self = this; 

    model.findOne({email : this.email}, 'email', function(err, results) { 
     if(err) { 
      done(err); 
     } else if(results) { 
      console.warn('results', results); 
      self.invalidate("email", "email must be unique"); 
      done(new Error("email must be unique")); 
     } else { 
      done(); 
     } 
    }); 

    next(); 
}); 

Tuy nhiên, nó không hoạt động!

Users.create() sẽ vẫn trả về số MongoError: E11000 duplicate key error indexconsole.warn() chỉ được gọi sau đó.

Hành động lưu không nên được gọi cho đến khi tất cả phần mềm trung gian done() được gọi theo tài liệu và tôi sẽ lấy lại lỗi xác thực.

Dường như hành vi done() không hoạt động như mong đợi,

Bất cứ ý tưởng tại sao?

Trả lời

37

Bạn đang sử dụng chức năng gọi lại phần mềm trung gian song song (với cả hai nextdone), nhưng bạn không đặt cờ song song trong tham số schema.pre để sử dụng các quy tắc nối tiếp.

Vì vậy, một trong hai bao gồm cờ song song trong cuộc gọi của bạn:

schema.pre("save", true, function(next, done) { ... 

Hoặc chuyển sang một phong cách callback middleware serial nếu đó là tất cả các bạn cần anyway:

schema.pre("save", function(next) { 
    var self = this; 

    model.findOne({email : this.email}, 'email', function(err, results) { 
     if(err) { 
      next(err); 
     } else if(results) { 
      console.warn('results', results); 
      self.invalidate("email", "email must be unique"); 
      next(new Error("email must be unique")); 
     } else { 
      next(); 
     } 
    }); 
}); 
+0

Phiên bản nào của Mongoose Điều này áp dụng đối với ? Tôi không thể tìm thấy bất kỳ tài liệu nào về chữ ký song song này cho 'schema.pre' mà bạn đang sử dụng trong đoạn mã của mình. –

+1

@PeterLyons Tùy chọn song song đã trở lại khoảng 2.x ít nhất. Xem http://mongoosejs.com/docs/middleware.html cho tài liệu. – JohnnyHK

+0

@JohnnyHK tôi có thể gửi mã trạng thái trong() tiếp theo không? Nếu tôi muốn từ chối yêu cầu, điều đó không lưu yêu cầu trong cơ sở dữ liệu và gửi mã trạng thái? là nó có thể? – nirvair

Các vấn đề liên quan