2015-09-28 222 views
0

我有一个身份验证方法,您可以在下面找到它。在该方法中,我根据授予类型调用不同的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); 
    } 

} 

在这里,在情况下,模式失败的堆栈跟踪:

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) 
+0

在以后的任何时候你会发现错误? – mido

+0

这是什么'回复'功能,如果从哪里来?源(或文档)是否可用? – Bergi

+0

回复函数来自[hapijs](http://hapijs.com/) – Safari

回答

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); 
} 
-2

我不完全得到你的问题,但是从我能理解,你不应该在使用承诺时抛出错误。相反reject承诺,如果有错误。

+0

是拒绝是一个好的观点,但我需要捕捉那个错误,然后通过Boom库抛出一个错误以获得一个很好的结果api用户响应和自定义状态代码。 – Safari

+0

我会想象你可以发送一个'Error'的实例来兴奋错误 – riyadhalnur

+0

@Safari为什么你不试图抛出一个自定义的错误对象抛出新的错误({code:100,message:''})然后在承诺链的最后,抓住它并按照你想要的方式进行处理? –