为什么我的JS承诺会将错误对象捕获为空?

时间:2016-07-21 20:11:41

标签: javascript node.js error-handling promise try-catch

前言

  • 使用Mongoose
  • 使用Bluebird并替换Mongoose内部的mpromise
  • 下面看到的req.helpers.consoleMessage函数是一个函数,其中包含一些简单的逻辑,根据应用程序配置中打开的调试是否存在,确定何时显示某个详细信息和不显示特定级别的详细信息显示的对象的null / undefined状态。整个消息使用JSON进行字符串化并返回以显示在控制台上。

代码:

以下是显示这些症状的一些代码示例。

这是我正在处理的API中delete :team个单元的:comment路由。我故意让行var response = user.comments;在引用user对象时出错,而实际上它应该是team,它应由调用函数返回并传递给Promise { {1}}。这会导致引用错误,因为未定义用户。

.then()

症状:

调用此路由将产生错误并导致 var console = clim("(DELETE /api/v1/team/:team/comments/:comment):", logger); // create a filters request for mongoose var query = {}; // determine if the :team param is a username or an object id req.helpers.validateObjectId(req.db, req.params.team) ? query._id = req.params.team : query.name = req.params.team; if(req.helpers.validateObjectId(req.db, req.params.comment)) { // looks good; create an update object var update = { $pull: { comments: { _id: req.params.comment } } }; // find the comment using the query above and pull the comment id req.models.Team.findOneAndUpdate( query, update, {safe: true, new : true} ).then(function(team){ if(!team){ // create the response object var response = { success: false, message: "Team not found" }; // log request console.info(req.helpers.consoleMessage(req, response, null)); // respond with an appropriate array res.status(404).json(response); }else{ // create the response object using the teams's comments var response = user.comments; // log request console.info(req.helpers.consoleMessage(req, response, null)); // respond with the team comments array res.status(200).json(response); } }).then(null, function(err){ // create the response var response = { success: false, message: req.config.debug ? err: "An error has occur with your request; please try again" }; // log the errors console.error(req.helpers.consoleMessage(req, response, err)); // or send a 500 internal server error res.status(500).json(response); }); }else{ // create the response var response = { success: false, message: "Comment id is not a valid object id" }; // log the errors console.info(req.helpers.consoleMessage(req, response, null)); // or send a 500 internal server error res.status(500).json(response); } 触发以尝试从错误状态恢复,但.catch()对象似乎为空。

实施例。 HTTP响应:err

实施例。控制台日志(为清晰起见而删节){ success: false, message: {} }

结论:

{ req: {...}, res: {...}. err: {} }对象似乎是空的......

2 个答案:

答案 0 :(得分:18)

<强>问题:

将错误对象单独记录到控制台将显示该对象确实不是空的,并且抓取err等属性是非常可行的。

问题是JS Error对象不能使用err.message天真地字符串化。在相关的SOF问题Is it not possible to stringify an Error using JSON.stringify?中详细描述了这一点以及处理此问题的方法。

更新代码:

进行了以下代码更改以指定消息显示在HTTP响应中,并且辅助函数(先前描述)已更新为特定要显示的错误的详细信息:Ex:JSON等等上。

{ err: { message: err.message, stack: err.stack } }

为什么我要分享这么简单的概念?

我搜索了几个小时,试图弄清楚我的诺言链结构错误地做了什么,并使用了关键字 var console = clim("(DELETE /api/v1/team/:team/comments/:comment):", logger); // create a filters request for mongoose var query = {}; // determine if the :team param is a username or an object id req.helpers.validateObjectId(req.db, req.params.team) ? query._id = req.params.team : query.name = req.params.team; if(req.helpers.validateObjectId(req.db, req.params.comment)) { // looks good; create an update object var update = { $pull: { comments: { _id: req.params.comment } } }; // find the comment using the query above and pull the comment id req.models.Team.findOneAndUpdate( query, update, {safe: true, new : true} ).then(function(team){ if(!team){ // create the response object var response = { success: false, message: "Team not found" }; // log request console.info(req.helpers.consoleMessage(req, response, null)); // respond with an appropriate array res.status(404).json(response); }else{ // create the response object using the teams's comments var response = team.comments; // log request console.info(req.helpers.consoleMessage(req, response, null)); // respond with the team comments array res.status(200).json(response); } }).then(null, function(err){ // create the response var response = { success: false, message: req.config.debug ? err.message : "An error has occur with your request; please try again" }; // log the errors console.error(req.helpers.consoleMessage(req, response, err)); // or send a 500 internal server error res.status(500).json(response); }); }else{ // create the response var response = { success: false, message: "Comment id is not a valid object id" }; // log the errors console.info(req.helpers.consoleMessage(req, response, null)); // or send a 500 internal server error res.status(500).json(response); } empty(以及关于JS Promises的每个词组合)但没有我的搜索提出了一些有用的东西,除了确认我正在接近这个。我的助手脚本似乎一切都很好,我似乎无法做正确的调试步骤来找出问题所在,直到我试图将error对象直接输出到控制台时(为什么我会需要这样做吗?我已经......或者我认为)。

所以我猜你可以说我试图挽救一些人,以防万一有人遇到类似的情况并且正在思考“为什么我的承诺不按预期工作!”和我一样,碰巧正朝着错误的方向寻找。

快乐的编码!

答案 1 :(得分:3)

当您尝试使用 JSON.stringify

时出现空对象问题
const error = new Error('Oops');
const output = JSON.stringify(error);
console.log(output); // {}
const error = new Error('Oops');
const output = JSON.stringify(error.message); // <--- Use error.message to fix that
console.log(output); // "Oops"