2014-12-09 14 views
5

Node.js dosyasında, akış denetimi hataları kullanmalı mıyım yoksa bunları istisnalar gibi mi kullanmalıyım?NodeJS en iyi yöntemler: Akış kontrolü için hatalar?

Sails.js'de bir kimlik doğrulama denetleyicisi ve bazı birim testleri yazıyorum ve şu anda, kayıt yöntemim aynı kullanıcı adına sahip bir kullanıcının olup olmadığını kontrol ediyor. Bir kullanıcı zaten kullanıcı adıyla varsa, benim modeli yöntemi öylesine gibi yeni bir hata nesnesi ile geri arama argümanları çağırır:

Modeli:

exists: function (options, cb) { 
    User.findOne({ 
     where: { username: typeof options === 'Object' && options.username ? options.username : options }, 
    }).exec(function (err, user) { 
     if (err) return cb(err); 
     if (user) return cb(new Error("A user with that username already exists.")); 
     cb(null, !!user); 
    }); 
}, 

Denetleyici:

User.exists(req.body.user.username, function (err, exists) { 
    if (err) { 
    console.log("error: ", err); 
    return res.status(409).json({ 
     message: err 
    });  
    } 

    User.create(req.user).then(function (data) { 
    res.status(201).json({ 
     user: data 
    }); 
    }); 
}); 

bu en iyisi bu uygulama? Düğüm sözleşmelerinin istisnai durumlar için hatalardan veya akış kontrolünden yana olup olmadığından emin değilim. Bunu yeniden yazmalıyım, ama bunu yapmadan önce kuralları bilmek istiyorum. Sanırım Sails'de bu şekilde yazılmış bazı örnekler gördüm. Teşekkürler! Programda senin hatalara daha semantik anlam vermek

if (something_went_wrong) { 
    throw new Error('Doh!'); 
} 

Ayrıca varsayılan hata nesnesine ek parametreleri ekleyebilirsiniz:

+0

Daha basit bir yolu bayrağına modeli şemada 'username' olarak tektir ve sadece kullanım Mongoose, "User.create()' denetleyicinizde 409 ile yanıt vermek için döner. Bu, daha iyimser bir yaklaşımdır, çünkü kullanıcı mevcut değilse ve geçerli bir isteği varsa, DB'yi hiçbir sebepten iki kez vurmazsınız . – srquinn

+0

@jibsales Bu mantıklı - ama sonra, 500 cevabı gerektiren farklı bir hata varsa ne olur?C# gibi dillerde, farklı istisnalar vardır ve bu türü kontrol edebilirsiniz. İstediğimde Düğümde böyle bir şey yapabildiğimi biliyorum, ama bu genel uygulama mı? Şimdi verdiğim karar, uygulamanın geri kalanını oluşturma şeklimizi etkileyecektir. Yorumunuza göre, Node istisnai durumlar yerine akış kontrolü için hatalar kullanıyormuş gibi görünüyor. –

+0

Aşağıdaki cevabımı – srquinn

cevap

2

Yukarıdaki yanıt Express için iyidir, ancak Sails denetleyicilerinde next; En iyi uygulama her zaman bir cevap vermektir. Çoğu örnekte Sails kodu, denetleyici eylemi işlevine bir argüman olarak bile next'u görmezsiniz. Ayrıca, Sails'in nesnesinin nesnesine (res.serverError ve res.badRequest gibi) ve res.negotiate'a dayandığı ve hatanın durum koduna göre sizin için uygun işleyiciye yönlendirileceğini unutmayın. Yani örnek tweaked olabilir gibidir:

Modeli:

exists: function (options, cb) { 
    User.findOne({ 
     where: { username: typeof options === 'Object' && options.username ? options.username : options }, 
    }).exec(function (err, user) { 
     // res.negotiate will default to a 500 server error 
     if (err) return cb(err); 
     // res.negotiate will just output the status code and error object 
     // as JSON for codes between 400 and 500, unless you 
     // provide a custom view as api/responses/badRequest.ejs 
     if (user) return cb({ 
      status: 409, 
      message: "A user with that username already exists." 
     }); 
     cb(null, !!user); 
    }); 
}, 

Denetleyici:

User.exists(req.body.user.username, function (err, exists) { 
    // Let Sails handle those errors for you 
    if (err) {return res.negotiate(err);} 

    User.create(req.user).then(function (data) { 
    res.status(201).json({ 
     user: data 
    }); 
    }); 
}); 
+1

Bu cevabı doğru olarak işaretleyin - diğeri iyi iken, bu Yelkenlere özeldir. Kayıt için benzer bir şey yaptım, ama Hatayı genişleterek kendi Hata türlerimi oluşturdum ve Bluebird vaatlerini kullanarak türü kontrol ediyorum. –

2

Düğümü (veya JavaScript gerçekten) anahtar kelime throw kullanarak istisnalarla ilgili hataları atabilir . Bununla birlikte, rota işleyicinizde bir hata atmak istemezsiniz çünkü bu işleminizi ve sunucunuzu kilitler.

Sails'te rota işleyicileri kullanırken (veya gerçekten ifade et), kesinlikle hata türünü kontrol etmeli ve buna göre müşteriye cevap vermelisiniz. DB dahili bir hata ile yanıt durumda biz zincirin aşağı hata işleme katman tarafından alınır next() fonksiyonuna geçmesini

// -- Route handler 
app.get('/something', function (req, res, next) { 

    DB.create({ username: 'user' }, function (err, docs) { 

    if (err) { 

     // This checks to see if we have a unique error from MongoDB 
     // and send the appropriate response to the client 
     if (err.code === 11000 || error.code === 11001) { 
     return res.send(409); // or return res.json(409, {message: "User exists"}); 
     } 

     // Any other error type is assumed to be an internal error so we pass it 
     // down the chain to the error handler middleware 
     return next(err); 

    } 

    // This is a client error, not an internal error so we respond to the client 
    // with the appropriate client error type 
    if (docs.length === 0) return res.send(404); 

    if (user.notAuthorized) return res.send(403); 

    res.send('All Good'); 

    }); 

}); 

dikkat edin. Herhangi bir armoni 4 ile ilgili bir hata aracılık aracı olarak tanımlanır. Yelkenler muhtemelen bazı varsayılan hata işleyicisine sahiptir, ancak muhtemelen bunu geçersiz kılabilirsiniz - yalnızca Express kullanarak kazancımı kontrol etmeyi tercih ettiğimden bu bilgi için uygun dokümanları kontrol etmeniz gerekir.

+0

görüyorum. Bu durumda, akış kontrolü için hatalar kullanabilirim, fakat hata kodunu veya türünü veya ismini kontrol etmem gerekiyor. Bu, Mongo veya Sails'in hangi tür hatalar atabileceğini anlamanız gerektiği anlamına geliyor. Bence bu getirme görevinde ilerleme kaydediyorum. –

+0

@ jedd.ahyoung Hata-için-akış-kontrol anlamında 'err' değerleri anlamında bir hata oluştu. Akış kontrolü için * siz * kullanıp kullanmamanız farklı bir konudur. Ayrıca, kütüphaneleri proaktif hale getirmenin Node sözleşmelerinin normal vaat semantikleri lehine ilerlediğini düşünün. –

+0

@DaveNewton Gerçekten de. Yelkenler varsayılan olarak [Bluebird] (https://www.npmjs.org/package/bluebird) içeriyor ve ben gerçekten bunu kullanmayı tercih ediyordum. Ancak, Bluebird hatalar için bir 'catch()' metodu sağlar, ki yine de (harika olsa da) hata isimlerini ve türlerini kontrol etmek zorundayım. –

İlgili konular