处理javascript中两层之间的错误

我有一个node.js应用程序使用快递和3层(控制器,API和模型)。

控制器要求API层发布,编辑或添加对象(承诺样式)。 APIvalidation并执行请求(使用模型层(mongoose))。 控制器必须通过渲染错误页面或闪光消息来告诉客户他的请求是否被接受。 这是一个显示主要结构的小图表。

应用程序结构图

这是一个例子:

Controller: exports.doEdit = function(req, res) { var args; args = req.body; return app.api.mods.edit(req.getUserId(), req.params.id, args.name, args.value).then(function(status) { return res.send(200, "Saved!"); }).fail(function(err) { return res.send(400, err.message); }); }; API Layer: /* Edit a mod @param userid the current logged user id @param slug the slug of the mod @param field the field to be edited @param value the new value @permission mod:edit */ exports.edit = (function(userid, slug, field, value, callback) { return canThis(userid, "mod", "browse").then(function(can) { var Mod; Mod = mongoose.model("Mod"); return Mod.findOne({ slug: slug }, function(err, mod) { if (can === false && mod._id !== userid) { return callback(new Error("unauthorized")); } if (err || !mod) { if (err) { console.log(err); } return callback(new Error("Please try again")); } mod[field] = value; mod.save(); return callback("ok"); }); }); }).toPromise(this); 

如何为错误做出简单,灵活和干净的沟通?

我想添加一个像这样的JSON对象

 { status: "error", code: "404", id: "not_found", message: "Not found" } 

但是,如何将它添加到只需要消息的错误? 它是否灵活和“干净”?

整个项目可以在这里看到: https : //github.com/CraftYourModCorporation/OpenCubes

如果我理解你是正确的,你是问如何传播错误给客户提供足够的信息。

首先,javascript是dynamic的,所以你可以在将它传递给callback/响应之前,将你需要的属性添加到你的Error实例中。

  if (can === false && mod._id !== userid) { var error = new Error("unauthorized") error.code = 401 error.id = "not_authorized" return callback(error); } 

不要忘记,在关注点分离的问题上,每个层都有它自己的语义,并且必须封装下层。 error handling也是如此。 有时候让错误起作用是恰当的,但是在大多数情况下这是不好的,或者至less是糟糕的用户体验。 所以至less在Controller中,你应该把这里冒出的任何错误转换成用户/客户友好的http错误代码。 为此,您必须考虑错误对上一层的意义。

所以像res.send(404, err.message)这样的代码很容易,但不是很有帮助。 如果你真的想做一个好的error handling,那么你必须进一步做一些匹配在这里。 在Java这样的静态types语言中,你可以在Type上进行匹配。 对于JS来说也是可能的(使用instanceof),但是这不是很可靠。 但是你可以使用其他所有的属性或者引入自己的属性来定义错误types。

  var error = new Error("Some lengthy message for humans, who are reading log files") error.errType = require('./errorTypes').NOT_AUTORIZED callback(error) 

并在api的用户代码

  if(err){ if(err.errType === errorTypes.NOT_AUTHORIZED) return res.send(401, "Wrong credentials") } 

你可以减less代码重复,提取错误匹配到一个自己的模块或一个简单的函数,将内部types映射到外部。

所以这很简单(不一样简单,容易取决于你的上下文),而且它在callback风格代码的意义上是干净的。 对于基于promise的apis也是一样的,只有在那里你有错误传播和parsing和拒绝控制stream程的分离。

我不介绍的东西像Node.js域名(因为它们不易于使用快递)和Zone.js的东西。 这可能会带来另一个工具链来处理错误,但本质上它仍然是一样的。 你必须在某处转换错误。