try / catch块或错误处理程序未捕获Lambda错误

时间:2018-12-18 21:53:46

标签: javascript aws-lambda alexa-skills-kit

我正在尝试记录在Lambda函数中运行的alexa技能中的错误,但是无论我如何尝试,错误都会以某种方式通过我的try/catch块而不会被记录。

这是我的index.js

const Alexa = require('ask-sdk-core');

try {
  const handlers = require('./handlers');

  const wrappedHandlers = handlers.map(handler => ({
    ...handler,
    async handle(handlerInput) {
      try {
        console.log(`Running handler ${handler.name}`, JSON.stringify(handlerInput, null, 2));
        const response = await handler.handle(handlerInput);
        console.log(`Successfully ran handler ${handler.name}`, JSON.stringify(response, null, 2));
        return response;
      } catch(error) {
        console.log(`Failed to run handler ${handler.name}`, error.stack);
        throw error;
      }
    },
  }));

  exports.handler = Alexa.SkillBuilders
    .custom()
    .addRequestHandlers(...wrappedHandlers)
    .addErrorHandlers(require('./handlers/error'))
    .lambda();
} catch(error) {
  console.log('Fatal initialization error', error);
  exports.handler = Alexa.SkillBuilders
    .custom()
    .addRequestHandlers({
      canHandle() { return true; },
      handle(handlerInput) {
        return handlerInput.responseBuilder
          .speak(`Initialization error`, error.stack);
      },
    })
    .lambda();
}

顶级try/catch应该捕获require('./handlers')期间引发的所有错误。过去,我已经观察到这种方法在我的处理程序中捕获语法错误。

我还将每个处理程序的handle函数包装在try/catch中(请参阅wrappedHandlers)。我的错误处理程序还会记录它看到的所有错误:

// handlers/error.js
module.exports = {
  canHandle() { return true; },

  handle(handlerInput, error) {
    console.log(`Error handled: ${error.stack}`);

    // During tests, include the error in the response
    if(process.env['NODE_ENV'] === 'test') {
      const { attributesManager } = handlerInput;
      const sessionAttributes = attributesManager.getSessionAttributes();
      sessionAttributes.error = error;
      attributesManager.setSessionAttributes(sessionAttributes);
    }

    const message = error && error.speachMessage || `Sorry, I can't understand the command. Please say again. ${error.stack}`;
    return handlerInput.responseBuilder
      .speak(message)
      .reprompt(message)
      .getResponse();
  },
};

尽管所有这些,Alexa模拟器还是吐出[Error]: An unexpected error occurred.,但是cloudwatch日志中没有任何错误或失败的请求。这怎么可能?

2 个答案:

答案 0 :(得分:0)

我也遇到了这个问题,并且有一个函数随lambda 502错误网关一起抛出,cloudwatch日志条目包含

Invoke Error {"errorType":"UnauthorizedError","errorMessage":"Forbidden","name":"UnauthorizedError","stack":["UnauthorizedError: Forbidden"," at /var/task/ApiServerClass.js:57:27"," at processTicksAndRejections (internal/process/task_queues.js:97:5)"," at async module.exports.me (/var/task/ApiServerClass.js:68:43)"," at async module.exports.run (/var/task/ApplicationClass.js:42:22)"]}

但是包裹整个功能的是try/catch

就好像抛出异常会立即导致lambda退出,而所有异常处理都将被忽略。但是当通过摩卡运行本地测试时。尊重例外情况

答案 1 :(得分:-1)

您是否在异步函数中尝试了普通for loop并在其中等待? 我遇到了同样的问题,并使用正常的for循环解决了问题,并在其中等待并发现了错误 ....我知道这肯定是愚蠢的回答,而且性能很慢

真正的答案如下:

async function functionName () {
  let results;
  try {
    results = await Promise.all(things.map(b)); // throws when any of the promises 
  } catch (err) {
    return console.log(err) // handle error
  }
  return results;
}

只需尝试在异步函数内用handlers.mapawait Promise.all()包裹起来,并处理将在此map()内引发的任何错误。

参考Handling Errors (Rejections) in async/await inside Array#map