Javascript 为什么我的JS promise catch错误对象是空的?

Javascript 为什么我的JS promise catch错误对象是空的?,javascript,node.js,error-handling,promise,try-catch,Javascript,Node.js,Error Handling,Promise,Try Catch,前言: 使用猫鼬 使用蓝鸟并在猫鼬体内更换mpromise 下面所示的req.helpers.consoleMessage函数是一个具有一些简单逻辑的函数,它根据应用程序配置中打开的调试的存在和显示的对象的非空/未定义状态,确定何时显示和不显示某一级别的详细信息。整个消息使用JSON字符串化,并返回到控制台上显示 代码: 下面是显示这些症状的一些代码的示例 这是我正在处理的API中:team:comment单元的删除路径。我故意留下了行var response=user.comments引用

前言:

  • 使用猫鼬
  • 使用蓝鸟并在猫鼬体内更换mpromise
  • 下面所示的
    req.helpers.consoleMessage
    函数是一个具有一些简单逻辑的函数,它根据应用程序配置中打开的调试的存在和显示的对象的非空/未定义状态,确定何时显示和不显示某一级别的详细信息。整个消息使用
    JSON
    字符串化,并返回到控制台上显示
代码:

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

这是我正在处理的API中
:team
:comment
单元的
删除
路径。我故意留下了行
var response=user.comments
引用了
用户
对象时出错,而实际上它应该是
团队
,调用函数应将其返回并传递到Promise
。然后()
。这将导致引用错误,因为未定义用户

    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响应:
{success:false,消息:{}

例如,控制台日志(为清晰起见进行了删节)
{req:{…},res:{…}.err:{}}

结论:


err
对象似乎为空

问题:

将错误对象本身记录到控制台将显示该对象确实不是空的,并且抓取诸如
err.message
之类的属性是非常可行的

问题是JS错误对象不能使用
JSON
进行简单的字符串化。相关的SOF问题中详细描述了这一点以及处理此问题的方法:

更新代码:

对以下代码进行了更改,以指定要在HTTP响应中显示的消息,并更新了helper函数(前面描述的)以指定要显示的错误的详细信息:Ex:
{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
error
(以及与JS承诺相关的每一个单词组合),但除了确认我正确地实现了这一点之外,我没有找到任何有用的搜索结果。我的助手脚本似乎一切正常,我似乎无法执行正确的调试步骤来找出问题所在,直到我尝试将
err
对象直接输出到控制台(为什么我需要这样做?我已经这样做了……或者我想是这样)

因此,我想你可以说,我正在努力为一些人节省一些时间,以防有人遇到类似的情况,并思考“为什么我的承诺没有按预期的那样发挥作用!”并且,像我一样,碰巧在寻找错误的方向


快乐编码

对于那些想知道为什么
throw error()
只是一个空对象的人来说,这是因为您需要将它记录为
error.message
访问它的
message
属性。

当您试图使用
JSON.stringify

const error=新错误('Oops');
const output=JSON.stringify(错误);
console.log(输出);//{}
const error=新错误('Oops');

const output=JSON.stringify(error.message);//酷!谢谢分享。哈,我犯了完全相同的错误。这是我今天在堆栈溢出方面最有用的东西。谢谢