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

标签 node.js mongodb express error-handling mongoose

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

organisation

问题: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));

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

我尝试过的另一个解决方案:

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

在 Controller 中(在 promise 之后)

.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 等)放入错误文件中并包含该文件。所以很可能是 newErrors.NotFoundError();

然后,在您的 Controller 中,您可以有一个失败回调函数,如下所示:

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

只有当 err 是 HttpError 类的实例时,这才有效。

关于node.js - 如何处理内部服务器 API 和 HTTP API 之间的错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25550286/

相关文章:

ruby - 登录 MongoDB 集合 (Ruby)

javascript - 将$ geoNear与另一个收藏集结合

node.js - Node 中的 Express 模块导出函数或对象

node.js - 如何使终端命令等待另一个命令完成?

node.js - 无法读取 heroku 中保存的文件

javascript - 如何在node.js中导出多个mongoose模型模块

javascript - 处理付款处理成功但数据库更新失败

node.js - elasticsearch.js:updateByQuery(如果存在),否则插入

javascript - 使用postman上传图片到nodejs后端服务

node.js - 如何在本地主机中运行多个express/Nodejs应用程序?