NodeJS最佳实践:stream量控制错误?

在Node.js中,我应该使用错误进行stream量控制,还是应该使用它们更像是exception?

我正在编写身份validation控制器和Sails.js中的一些unit testing,目前,我的注册方法检查是否存在具有相同用户名的用户。 如果一个用户已经存在用户名,我的模型方法用一个新的Error对象调用它的callback参数,如下所示:

模型:

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); }); }, 

控制器:

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

这是最佳做法吗? 我不确定节点约定是否支持exception情况下的错误,或stream量控制。 我想我应该重写这个,但是我想在这之前知道约定。 我想我已经在Sails中看到了一些这样写的例子。 谢谢!

上面的答案对Express来说是好的,但是在Sails控制器中,你不应该在next调用; 最好的做法是总是回复一个回复。 在大多数示例的Sails代码中,你甚至不会看到next作为控制器动作函数的参数。 还要注意,Sails提供了一些默认的响应方法 ,比如res.serverErrorres.badRequest ,以及res.negotiate ,它们会根据状态尝试将错误路由到适当的处理程序码。 所以你的例子可以调整为:

模型:

 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); }); }, 

控制器:

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

节点(或者真的是Javascript)可以使用关键字throwexception:

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

您还可以将其他参数添加到默认的Error对象,以便在程序中为您的错误提供更多的语义。 这样说,你不会想在你的路由处理程序中抛出一个错误,因为这会导致进程和服务器崩溃。

当在Sails中使用路由处理程序时(或者真的expression),你当然应该检查错误的types并相应地响应客户端。

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

注意,在数据库响应一个内部错误的情况下,我们传递给next()函数,该函数由链中的error handling中间件拾取。 任何具有4的中间件被定义为error handling中间件。 Sails可能有一些默认的error handling程序,但是你也可以覆盖它 – 你需要检查这个信息的适当的文档,因为我更喜欢使用Express单独获得的控制。