web-dev-qa-db-ja.com

JSプロミスキャッチエラーオブジェクトが空になるのはなぜですか?

序文:

  • マングースの使用
  • Bluebirdを使用してMongoose内でmpromiseを置き換える
  • 以下に表示される_req.helpers.consoleMessage_関数は、アプリ構成でオンになっているデバッグの存在と非null /未定義に基づいて、特定の詳細レベルをいつ表示するか、または表示しないかを決定するいくつかの単純なロジックを含む関数です表示されているオブジェクトの状態。メッセージ全体は、JSONを使用して文字列化され、コンソールに表示されるように返されます。

コード:

これらの症状を示すコードの例を次に示します。

これは、私が取り組んでいるAPIのthe _:team_ _:comment_ユニットのdeleteルートです。 userオブジェクトを参照しているときに実際にteamであるはずの_var response = user.comments;_行を意図的に残しましたが、実際には、呼び出し元の関数によって返され、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応答:_{ success: false, message: {} }_

例コンソールログ(明確にするために省略)_{ req: {...}, res: {...}. err: {} }_

結論:

errオブジェクトが空のようです...

21
ccampanale

問題:

エラーオブジェクト自体をコンソールに記録すると、オブジェクトが実際に空ではなく、err.messageなどのプロパティの取得が非常に可能であることがわかります。

問題は、JSエラーオブジェクトをJSONを使用して単純に文字列化できないことです。これは、この問題に対処する方法とともに、関連するSOF質問で詳細に説明されています: JSON.stringifyを使用してエラーを文字列化することはできませんか?

更新されたコード:

次のコード変更は、メッセージがHTTP応答に表示されるように指定され、ヘルパー関数(前述)が表示されるエラーの詳細に更新されました。例:{ 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オブジェクトをコンソールに直接出力しようとするまでは、問題がどこにあるのかを理解するための正しいデバッグ手順を実行できなかったようです(なぜ私はこれをする必要がありますか?私はすでにそうでした...または私はそう思いました)。

ですから、誰かが同じような状況に遭遇し、「なぜ私の約束が意図したとおりに機能しないのか」と考えている場合に備えて、時間を節約しようとしていると言えるでしょう。そして、私のように、たまたま間違った方向を探しています。

ハッピーコーディング!

25
ccampanale