如何处理内部服务器API和HTTP API之间的错误

这就是我的node.js服务器的组织方式

组织

问题 :API通过模型(mongoose)向我的mongodb数据库发出请求。 所以在API层我可以有:

User.findById(id, function(user) { if(user._id !== userid) return deferred.reject(new Error()); // ?? if(!user) return deferred.reject(new Error()); // ?? user[field] = value; user.save(function() { deferred.resolve(user); }); }); 

但是,我应该抛出什么错误? 什么方法更合适,更方便用户。 我可以尝试例如:

  if(user._id !== userid) return deferred.reject(new Error(403)); 

但是这意味着没有消息,只是错误代码:/

另一个解决scheme

 exports.errors = errors = NOT_FOUND: id: "NOT_FOUND" code: 404 message: "Can't found requested object. Please retry" UNAUTHORIZED: id: "UNAUTHORIZED" code: 401 message: "Please login first" FORBIDDEN: id: "FORBIDDEN" code: 403 message: "Access denied." DATABASE_ERROR: id: "DATABASE_ERROR" code: 500 message: "Error with databse. Please retry" exports.throwError = throwError = (message, id) -> if typeof message is "string" then err = new Error message else err = message err.type = id err.data = errors[id] return err exports.handleHttp = (err, req, res, format="text") -> console.log(" Error - #{err.message} (#{err.type}) on #{req.url}".red) console.log(err.stack) if format is "text" res.send err.data.code, "#{err.data.type}: #{err.message}" if format is "json" res.send err.data.code, type: err.data.type message: err.message id: err.type status: "error" errors: err.errors 

所以我会这样使用它:

  if(user._id !== userid) return deferred.reject(error.throwError("Forbidden", "UNAUTHORIZED")); 

而在控制器(承诺之后)

 .fail (err)-> errors.handleHttp err, req, res, "json" 

但是我不喜欢这个解决办法,这让我感到很痛苦,不满意。 任何其他的想法?

您可以定义扩展现有Error对象的新的Error对象。 例如,以下是404错误:

 function HttpError(message, code) { this.message = message || ""; this.code = code || 500; } HttpError.prototype = Object.create(Error.prototype); HttpError.prototype.send = function send(req, res) { var type = req.accepts("json", "html", "text"); switch(type) { case "json": res.send(this.code, JSON.stringify(this)); break; case "html": case "text": res.send(this.code, "An error occurred: " + this.message); break; } }; function NotFoundError(message, code) { this.name = "NotFound"; this.message = message || "Could not find the object you were requesting"; this.code = code || 404; } NotFoundError.prototype = Object.create(HttpError.prototype); 

你可以像这样使用它:

 User.findById(id, function(user) { if(!user) return deferred.reject(new NotFoundError()); user[field] = value; user.save(function() { deferred.resolve(user); }); }); 

您可以将所有错误(500,404,401等)放在错误文件中并包含该错误。 所以这可能是new errors.NotFoundError();

然后,在你的控制器中,你可以有一个失败的callback函数,如下所示:

 getUser().fail(function(err) { err.send(req, res) }); 

这只会在err是HttpError类的实例时才起作用。