node.js - 无法处理 hystrix 模块中的 request-promise-json 错误

标签 node.js error-handling promise hystrix

我是 Node js 新手,我必须在 Node js 中为我的项目实现 hystrix 弹性库,但我陷入了困境。 我面临的问题是,每当我从服务器应用程序发送错误代码(4xx,5xx)时,我无法使用 Promise 来处理它们。 我正在粘贴 app.jsserver.js 文件的代码。虽然该项目还有其他几个文件,但这些文件用于启动所有进程,但唯一的问题是在 app.js 中。

请帮助我如何有效地处理被拒绝的 promise 错误,以便我不会在 app.js 的 isErrorHandler 方法中为 res,body 未定义。

我还将添加控制台数据。

app.js

var express = require('express'), Promise = require('q'), request = require('request'), getRandomInt = require('./random_int'), http = require('request-promise-json'), _ = require("lodash"), hystrixStream = require('../../lib/http/HystrixSSEStream'), CommandsFactory = require("../../lib/command/CommandFactory");

var makeRequest = function(options) {
    var req = _.assign(options);

    return http.request(req);
};


function hystrixStreamResponse(request, response) {
    response.append('Content-Type', 'text/event-stream;charset=UTF-8');
    response.append('Cache-Control',
            'no-cache, no-store, max-age=0, must-revalidate');
    response.append('Pragma', 'no-cache');
    return hystrixStream.toObservable().subscribe(function onNext(sseData) {
        response.write('data: ' + sseData + '\n\n');
    }, function onError(error) {
        console.log(error);
    }, function onComplete() {
        return response.end();
    });
}

// called from index.js when process.env.app is set
module.exports = function(port) {
    var app = express(), cbs = [], commands = [], reqs = 0;
    var isErrorHandler = function(error, res, body) {

        console.log("Entred error handler");
        console.log("error :" + error);
        console.log("res:" + res);
        console.log("body :" + body);

        if (res.statusCode == 503) {
            console.log("Entred 503 loop");
            var unavailableError = new Error();
            unavailableError.name = " Service Unavailable Error..";
            return unavailableError;
        }

        if (res.statusCode === 404) {
            console.log("Entred 404 loop");
            var notFoundError = new Error();
            notFoundError.name = " Avoided 404..";
            return notFoundError;
        }

        if (error) {
            console.log("Entred default error");
            return error;
        }

        return null;
    };

    // here we are configuring all external communication points within a
    // command
    // also starting point
    this.configure = function(config) {

        config.services.forEach(function(service) {
            var serviceCommand = CommandsFactory.getOrCreate(
                    "Service on port :" + service.port + ":" + port)
                    .circuitBreakerErrorThresholdPercentage(
                            service.errorThreshold).timeout(service.timeout)
                    .run(makeRequest).circuitBreakerRequestVolumeThreshold(
                            service.concurrency)
                    .circuitBreakerSleepWindowInMilliseconds(service.timeout)
                    .statisticalWindowLength(10000)
                    .statisticalWindowNumberOfBuckets(10).errorHandler(
                            isErrorHandler).build();
            serviceCommand.service = service;
            commands.push(serviceCommand);
        });
    };

    // this is called from stats.js for hystrix Stream Response
    app.get('/api/hystrix.stream', hystrixStreamResponse);




    app.get("/", function(req, res) {
        var promises = [];
        commands.forEach(function(command) {
            var n = getRandomInt(1, command.service.calls);
            for (var i = 0; i < n; i++) {
                var url = "http://127.0.0.1:3003";
                promises.push(command.execute(url).fail(function(error,response,body) {
                    console.log("Entered fail error:"+error);
                    console.log("Entered fail response:"+response);
                    console.log("Entered fail body:"+body); 
                     //res.send(reason , res, body);
                })
                );
            }
        });

        Promise.all(promises).then(function(results) {
           results.forEach(function(result) {
               res.send(results.join("\n"));
               res.set('Content-Type', 'text/plain');
               reqs++;
           });
        }).catch(function(error) {
            reqs++;
            res.send("Error: " + error);
        });
    });

    // the app.start() function is called from index.js file..
    this.start = function() {
        // port value is passed from index.js
        process.title = 'node (app:' + port + ')';

        app.listen(port, function() {
            // start variable represents when the app
            // started listening on a particular port
            var start = Date.now();
            console.log("[%d] APP Listening on %d,%d", process.pid, port,
                    process.title);

            // keeps calling this function after ever 1 second
            // reqs is a counter which keeps incrementing after every
            setInterval(function() {
                var elapsed = (Date.now() - start) / 1000;
                var rps = elapsed ? reqs / elapsed : 0;
                console.log("App req/s: " + rps + " : " + port);
            }, 1000);

        });
    };

};

服务器.js

var express = require('express'), getRandomInt = require('./random_int');

module.exports = function(port) {
    var app = express(), reqs = 0, sickPercentage = 20, maxSetSickTimeout = 5, sick = false, maintenancePercentage = 5, maxSetMaintenanceTimeout = 15, maintenance = false;

    function setSick() {
        sick = getRandomInt(0, 100) <= sickPercentage;// if smaller or equal
        // to 20 then make it
        // true..
        console.log("SERVICE: ", port, "sick", sick);
        setTimeout(setSick, 1000 * getRandomInt(0, maxSetSickTimeout));//5 is max sick timeout
    }

    function setMaintenance() {
        // if smaller or equal to 5 then make it true..else false
        maintenance = getRandomInt(0, 100) <= maintenancePercentage;

        console.log("SERVICE: ", port, "maintenance", maintenance);
        setTimeout(setMaintenance, 1000 * getRandomInt(0,maxSetMaintenanceTimeout));//5 is maxSetMaintenanceTimeout
    }

    //setSick();
    //setMaintenance();

    app.get("/", function(req, res) {
        reqs++;

        /*if (maintenance) {
            res.status(503).send("Temporaly Unavailable");
            return;
        }*/

        /*var ms;

        if (sick) {
            ms = getRandomInt(0, 10 * parseInt(req.params.ms));
        } else {
            ms = getRandomInt(0, parseInt(req.params.ms));
        }
        setTimeout(function() {
            res.send("OK: slept " + ms + " ms");
        }, ms);*/

        (reqs % 2) == 0 ? res.status(200).send('wooohhh loving it..') :res.status(404).send("Kindly Browse more...........");
        //res.status(200).send("All fine here");
        return;

    });

    this.start = function() {
        process.title = 'node (service:' + port + ')';
        app.listen(port, function() {
            var start = Date.now();
            console.log("[%d] SERVICE Listening on %d", process.pid, port);
            setInterval(function() {
                var elapsed = (Date.now() - start) / 1000;
                var rps = elapsed ? reqs / elapsed : 0; //rps=request processed per second
                console.log("Service req/s: " + rps+" : "+ port);//here they are printing requests processed per second
                process.send({
                    rps : rps
                });
            }, 1000);
        });
    };
};

/*

module.exports = function(port) {
    var app = express(), reqs = 0, sickPercentage = 20, maxSetSickTimeout = 5, sick = false, maintenancePercentage = 5, maxSetMaintenanceTimeout = 15, maintenance = false;

    function setSick() {
        sick = getRandomInt(0, 100) <= sickPercentage;// if smaller or equal
        // to 20 then make it
        // true..
        console.log("SERVICE: ", port, "sick", sick);
        setTimeout(setSick, 1000 * getRandomInt(0, maxSetSickTimeout));//5 is max sick timeout
    }

    function setMaintenance() {
        // if smaller or equal to 5 then make it true..else false
        maintenance = getRandomInt(0, 100) <= maintenancePercentage;

        console.log("SERVICE: ", port, "maintenance", maintenance);
        setTimeout(setMaintenance, 1000 * getRandomInt(0,maxSetMaintenanceTimeout));//5 is maxSetMaintenanceTimeout
    }

    setSick();
    setMaintenance();

    app.get("/random-sleep/:ms", function(req, res) {
        reqs++;

        if (maintenance) {
            res.status(503).send("Temporaly Unavailable");
            return;
        }

        var ms;

        if (sick) {
            ms = getRandomInt(0, 10 * parseInt(req.params.ms));
        } else {
            ms = getRandomInt(0, parseInt(req.params.ms));
        }
        setTimeout(function() {
            res.send("OK: slept " + ms + " ms");
        }, ms);
    });

    this.start = function() {
        process.title = 'node (service:' + port + ')';
        app.listen(port, function() {
            var start = Date.now();
            console.log("[%d] SERVICE Listening on %d", process.pid, port);
            setInterval(function() {
                var elapsed = (Date.now() - start) / 1000;
                var rps = elapsed ? reqs / elapsed : 0; //rps=request processed per second
                console.log("Service req/s: " + rps);//here they are printing requests processed per second
                process.send({
                    rps : rps
                });
            }, 1000);
        });
    };
};

*/

控制台输出:

The web UI will be on http://localhost:3000/
You have 5 seconds to abort...
5...
4...
3...
2...
1...
This will get a bit verbose...
[932] SERVICE Listening on 3003
[5664] APP Listening on 3004,NaN
Service req/s: 0 : 3003
App req/s: 0 : 3004
Service req/s: 0 : 3003
App req/s: 0 : 3004
Service req/s: 0 : 3003
App req/s: 0 : 3004
Service req/s: 0 : 3003
Entred error handler
error :StatusCodeError: undefined undefined failed with status code 404
res:undefined
body :undefined
Entered fail error:TypeError: Cannot read property 'statusCode' of undefined
Entered fail response:undefined
Entered fail body:undefined
App req/s: 0.2485707183693761 : 3004
Entred error handler
error :StatusCodeError: undefined undefined failed with status code 404
res:undefined
body :undefined
Entered fail error:TypeError: Cannot read property 'statusCode' of undefined
Entered fail response:undefined
Entered fail body:undefined
Service req/s: 0.5960659646334194 : 3003
App req/s: 0.39840637450199207 : 3004
Service req/s: 0.49677098857426727 : 3003
App req/s: 0.4980906524987548 : 3004
Service req/s: 0.5676979846721544 : 3003
Entred error handler
error :StatusCodeError: undefined undefined failed with status code 404
res:undefined
body :undefined
Entered fail error:TypeError: Cannot read property 'statusCode' of undefined
Entered fail response:undefined
Entered fail body:undefined
App req/s: 0.5692329585883023 : 3004
Service req/s: 0.7457121551081283 : 3003
Entred error handler
error :StatusCodeError: undefined undefined failed with status code 404
res:undefined
body :undefined
Entered fail error:TypeError: Cannot read property 'statusCode' of undefined
Entered fail response:undefined
Entered fail body:undefined
App req/s: 0.6222000995520159 : 3004
Entred error handler
error :StatusCodeError: undefined undefined failed with status code 404
res:undefined
body :undefined
Entered fail error:TypeError: Cannot read property 'statusCode' of undefined
Entered fail response:undefined
Entered fail body:undefined
Service req/s: 1.1042402826855124 : 3003
App req/s: 0.6637168141592921 : 3004
Entred error handler
error :StatusCodeError: undefined undefined failed with status code 404
res:undefined
body :undefined
Entered fail error:TypeError: Cannot read property 'statusCode' of undefined
Entered fail response:undefined
Entered fail body:undefined
Entred error handler
error :StatusCodeError: undefined undefined failed with status code 404
res:undefined
body :undefined
Entered fail error:TypeError: Cannot read property 'statusCode' of undefined
Entered fail response:undefined
Entered fail body:undefined
Service req/s: 1.29366106080207 : 3003
Entred error handler
error :StatusCodeError: undefined undefined failed with status code 404
res:undefined
body :undefined
Entered fail error:TypeError: Cannot read property 'statusCode' of undefined
Entered fail response:undefined
Entered fail body:undefined
App req/s: 0.9960159362549802 : 3004
Entred error handler
error :StatusCodeError: undefined undefined failed with status code 404
res:undefined
body :undefined
Entered fail error:TypeError: Cannot read property 'statusCode' of undefined
Entered fail response:undefined
Entered fail body:undefined
Entred error handler
error :StatusCodeError: undefined undefined failed with status code 404
res:undefined
body :undefined
Entered fail error:TypeError: Cannot read property 'statusCode' of undefined
Entered fail response:undefined
Entered fail body:undefined
Entred error handler
error :StatusCodeError: undefined undefined failed with status code 404
res:undefined
body :undefined
Entered fail error:TypeError: Cannot read property 'statusCode' of undefined
Entered fail response:undefined
Entered fail body:undefined
Service req/s: 1.9009685887571286 : 3003
Entred error handler
error :StatusCodeError: undefined undefined failed with status code 404
res:undefined
body :undefined
Entered fail error:TypeError: Cannot read property 'statusCode' of undefined
Entered fail response:undefined
Entered fail body:undefined
Entred error handler
error :StatusCodeError: undefined undefined failed with status code 404
res:undefined
body :undefined
Entered fail error:TypeError: Cannot read property 'statusCode' of undefined
Entered fail response:undefined
Entered fail body:undefined
App req/s: 1.4508523757707652 : 3004
Entred error handler
error :StatusCodeError: undefined undefined failed with status code 404
res:undefined
body :undefined
Entered fail error:TypeError: Cannot read property 'statusCode' of undefined
Entered fail response:undefined
Entered fail body:undefined
Entred error handler
error :StatusCodeError: undefined undefined failed with status code 404
res:undefined
body :undefined
Entered fail error:TypeError: Cannot read property 'statusCode' of undefined
Entered fail response:undefined
Entered fail body:undefined
Service req/s: 2.4896265560165975 : 3003
Entred error handler
error :StatusCodeError: undefined undefined failed with status code 404
res:undefined
body :undefined
Entered fail error:TypeError: Cannot read property 'statusCode' of undefined
Entered fail response:undefined
Entered fail body:undefined
Entred error handler
error :StatusCodeError: undefined undefined failed with status code 404
res:undefined
body :undefined
Entered fail error:TypeError: Cannot read property 'statusCode' of undefined
Entered fail response:undefined
Entered fail body:undefined
Entred error handler
error :StatusCodeError: undefined undefined failed with status code 404
res:undefined
body :undefined
Entered fail error:TypeError: Cannot read property 'statusCode' of undefined
Entered fail response:undefined
Entered fail body:undefined
App req/s: 1.8281535648994514 : 3004
Service req/s: 2.6813759289052324 : 3003
App req/s: 1.686987194233571 : 3004
Service req/s: 2.4903941938238225 : 3003
App req/s: 1.566728386269762 : 3004

如果我没有错,那么问题只是在处理执行返回 4xx,5xx 错误的请求的 promise 时..

最佳答案

传递给 errorHandler 的函数不会传递任意输入,仅传递错误对象。您应该能够获取错误的状态代码。

关于node.js - 无法处理 hystrix 模块中的 request-promise-json 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34152916/

相关文章:

json - JSONEncoder.encode 在 Swift 中抛出什么异常?

javascript - 将 async/await 与 forEach 循环结合使用

javascript - Node passport-local 策略总是失败

error-handling - 如果将所有错误都改为包含文件名、函数名和行号的样式,会出现什么潜在问题吗?

node.js - 当 package.json 版本不正确时从 npm 迁移到 Yarn

python - 在 Python 脚本中解析 JSON 数据时遇到问题

javascript - 无法访问 for 循环中使用的链式 promise 内的外部作用域变量

javascript - 在单个 Javascript 函数中处理多个 websocket 订阅,但只处理一个连接对象

node.js - Jade模板,如何将具体对象传递给页面?

javascript - 重定向到 Node JS 路由中的另一个源路径(跨域)