承诺:未处理未处理的异常

时间:2015-09-28 08:19:50

标签: javascript node.js promise bluebird unhandled-exception

我有一个验证方法,您可以在下面找到。在该方法中,我根据授权类型调用不同的Joi Schema验证和令牌验证函数。代码工作基本上非常好,但如果我在方法中抛出错误" checkSchema"我在日志中获得了完整的堆栈跟踪,尽管hapis方法重放应该可以处理该错误。

我使用蓝鸟承诺,如果重要的话。

此处代码:

/**
 * checks if the given login informations are right and returns a token response
 * For each strategy you first validate the given payload and next you check if the given payload is ok.
 */
export function authenticate(request, reply) {

    var schema, checkMethod;

    switch (request.payload.grantType) {
        case "password":
            schema = passwordSchema;
            checkMethod = checkPasswordLogin;
            break;
        case "refreshToken":
            schema = refreshTokenSchema;
            checkMethod = checkRefreshTokenLogin;
            break;
        default:
            throw new Error("No valid Grant Type given");
    }
    var promise = Promise
        .try(function() {
            return checkSchema(request.payload, schema);
        })
        .then(function(value) {
            return checkMethod(value);
        })
        .then(function(userInstance) {
            return generateToken(userInstance);
        });

    reply(promise);
}

/**
 * checks if a payload followed a specific schema and throws an error if not
 */
function checkSchema(payload, schema) {
    try {
        Joi.assert(payload, schema);
    } catch (e) {
        throw Boom.create(400, e);
    }

}

这里是Schema失败时的堆栈跟踪:

Unhandled rejection Error: Error: {
  "grantType": "password",
  "username": "John",
  "password" [1]: -- missing --
}

[1] "password" is required
    at Object.exports.create (/server/test-backend/node_modules/boom/lib/index.
js:21:17)
    at checkSchema (/source/api/controllers/app/auth.ts:48:20)
    at /source/api/controllers/app/auth.ts:29:20
    at tryCatcher (/server/test-backend/node_modules/bluebird/js/main/util.js:2
6:23)
    at Function.Promise.attempt.Promise.try (/server/test-backend/node_modules/
bluebird/js/main/method.js:31:24)
    at authenticate (/source/api/controllers/app/auth.ts:28:13)
    at Object.internals.handler (/server/test-backend/node_modules/hapi/lib/han
dler.js:94:36)
    at /server/test-backend/node_modules/hapi/lib/handler.js:28:23
    at [object Object].internals.Protect.run (/server/test-backend/node_modules
/hapi/lib/protect.js:56:5)
    at exports.execute (/server/test-backend/node_modules/hapi/lib/handler.js:2
2:22)
    at /server/test-backend/node_modules/hapi/lib/request.js:370:13
    at iterate (/server/test-backend/node_modules/hapi/node_modules/items/lib/i
ndex.js:35:13)
    at done (/server/test-backend/node_modules/hapi/node_modules/items/lib/inde
x.js:27:25)
    at /server/test-backend/node_modules/hoek/lib/index.js:841:22
    at /server/test-backend/node_modules/continuation-local-storage/node_module
s/async-listener/glue.js:188:31
    at process._tickDomainCallback [as _tickCallback] (node.js:486:13)

2 个答案:

答案 0 :(得分:0)

我目前通过编写下面的代码修复它。不幸的是,我不知道为什么如果我在checkMethod中抛出错误一切都很好,但如果我在checkSchema中抛出错误,我需要手工捕获所有错误(hapi js不是为我处理的)

/**
 * checks if the given login informations are right and returns a token response
 * For each strategy you first validate the given payload and next you check if the given payload is ok.
 */
export function authenticate(request, reply) {

    var schema, checkMethod;

    switch (request.payload.grantType) {
        case "password":
            schema = passwordSchema;
            checkMethod = checkPasswordLogin;
            break;
        case "refreshToken":
            schema = refreshTokenSchema;
            checkMethod = checkRefreshTokenLogin;
            break;
        default:
            throw new Error("No valid Grant Type given");
    }
    var promise = Promise
        .try(function() {
            return checkSchema(request.payload, schema);
        })
        .then(function() {
            return checkMethod(request.payload);
        })
        .then(function(userInstance) {
            return generateToken(userInstance);
        })
        .catch(function(err) {
            return err;
        });

    reply(promise);
}

/**
 * checks if a payload followed a specific schema and throws an error if not
 */
function checkSchema(payload, schema) {
    var result = Joi.validate(payload, schema);
    if (result.error) {
        return Promise.reject(Boom.wrap(result.error, 400));
    }
    return Promise.resolve(result.value);
}

答案 1 :(得分:-2)

我没有完全解决你的问题,但从我能理解的情况来看,你不应该在使用promises时抛出错误。相反,reject承诺如果有错误。