javascript - 为什么我的 JS promise 捕获错误对象为空?

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

前言:

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

代码:

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

这是我正在处理的 API 中 :team :comment 单元的 delete 路由。我故意离开 var response = user.comments; 行,在它引用 user 对象时出错,而实际上它应该是 team 应该由调用函数返回并传递给 Promise.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() 触发以尝试从错误状态中恢复,但是 err 对象似乎为空.

例如。 HTTP 响应:{ 成功:false,消息:{} }

例如。控制台日志(为清楚起见进行了删节){ req: {...}, res: {...}。错误:{}}

结论:

err 对象似乎是空的...

最佳答案

问题:

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

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

更新代码:

进行了以下代码更改以指定在 HTTP 响应中显示的消息,并且已更新帮助函数(之前描述)以具体显示要显示的错误的详细信息:例如:{ err: {消息:err.message,堆栈: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);

    }

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

我搜索了几个小时试图找出我在使用我的 promise 链结构时做错了什么,并使用了关键字 emptyerror(以及关于JS Promises),但除了确认我正在正确地处理这个问题之外,我的搜索都没有找到任何有用的东西。我的帮助脚本似乎一切都很好,我似乎无法执行正确的调试步骤来找出问题所在,直到我尝试将 err 对象直接输出到控制台(为什么我需要这样做?我已经……或者我想)。

所以我猜你可能会说我正在努力为一些人节省一些时间,以防有人遇到类似情况并思考“为什么我的 promise 没有按预期工作!”和我一样,碰巧在错误的方向搜索。

编码愉快!

关于javascript - 为什么我的 JS promise 捕获错误对象为空?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38513493/

相关文章:

javascript - 无法解析 'react/redux' 中的 "..\containers\CarForm.js"

javascript - 使用 jquery,获取具有特定类名的 "next"文本框的最佳方法是什么

javascript - 如何在 Javascript 中更新实时图表

javascript - DRY-er Javascript 类

javascript - 在 JavaScript 中实现 Stream

python - flask : Ignore if one file is not uploaded in form (containing multiple file upload options)

java - Heroku 在 gradle 任务 'nodeSetup' 期间构建失败,错误为 'Couldn' t follow 符号链接(symbolic link)'

node.js - 套接字io,node.js

c# - 添加错误处理以从数据库中删除用户

error-handling - 使用 FTP "append"命令