【问题标题】:Throwing errors/response outside exports.handler在exports.handler 之外抛出错误/响应
【发布时间】:2020-01-19 18:29:28
【问题描述】:

我刚刚开始将 AWS Lambda/Node.JS/API Gateway 与 API Lambda 代理集成一起使用,我正在努力解决一些应该很简单的事情。处理来自外部exports.handler的错误。

我已经开发了所有代码,一切正常,但是,我正在努力处理错误。我正在使用 async/await,没有回调。

基本上,我的代码如下所示:

exports.handler = async (event, context) => {
  const sampleVar = await sampleFunction();

  const response = {
    statusCode: 200,
    body: JSON.stringify(sampleVar),
    isBase64Encoded: false
  };
  return response;
}

很好,对吧?我的问题是我所有的“真实代码”都是在exports.handler之外以不同的功能开发的,比如:

async function sampleFunction() {
  const test = 123;
  return anotherFunction(test);
}

async function anotherFunction() {
  const test2 = 'blablabla';
  return test2;
}

现在,假设我的 sampleFunction 发生错误,我需要立即抛出错误。我可以去throw { statusCode: 400, etc, etc };,但是,如果我抛出错误,我会得到一个“500 Internal Server Error”作为我的响应,无论如何。如果我从exports.handler 函数中处理错误,我只能正确地破坏我的代码。那样的话,我可以去return { statusCode: 400, etc, etc };context.fail()等等,一切都会好起来的。

我的问题是:有什么方法可以“破解”我的代码并从我的 exports.handler 外部发送正确的响应?或者可能在外部调用我的 exports.handler 以返回特定响应?

【问题讨论】:

  • 愚蠢的问题,也许....您是否选中了“使用 Lambda 代理集成”框。如果您不这样做,那么在 Lambda 中设置 statusCode 将无关紧要......相反,您必须通过集成响应来处理该响应并执行 lambda 正则表达式查找
  • 是的,我已选中该框。问题是我不能只抛出一个正确的错误并从我的exports.handler 之外停止我的代码。我可能正在为如何发送将停止我的代码并返回正确响应的“全局”响应而苦苦挣扎。如果我使用“throw”,代码会在 500 Internal Server 处停止。
  • 所以,原因是因为正确的响应是您指定的对象(即{statusCode: 4xx, etc etc},抛出将返回错误,具有道具消息,stackTrace等。这不是api网关喜欢的,所以你很可能得到一个格式错误的响应。你的处理程序需要格式化响应...推断你的处理程序需要捕获任何抛出并相应地格式化响应

标签: node.js aws-lambda aws-api-gateway


【解决方案1】:

所以,我会在 cmets 中写这个,但是标记有点差。我会做如下的事情:

exports.handler = async (event, context) => {
  return await sampleFunction().then(craftOk).catch(craftErr);
}

function craftOk(res) {
  return {
    statusCode: 200,
    body: JSON.stringify(res),
    isBase64Encoded: false
  };
}

function craftBad(err) {
  return {
    statusCode: 400,
    body: err.message,
    isBase64Encoded: false
  }
}

为了好玩,我写了一个测试脚本来验证从异步/等待捕获的返回...也许它会有所帮助

function test(toggle) {
    return (toggle) ? Promise.resolve("yay") : Promise.reject(new Error("boo"))
}

async function main1() {
    let res =  await test(true).then( res => {
        return {
            statusCode: 200,
            body: res,
            isBase64Encoded: false            
        }
    })
    .catch(err => {
        return {
            statusCode: 400,
            body: err.message,
            isBase64Encoded: false            
        }
    })
    return res
}

async function main2() {
    let res =  await test(false).then( res => {
        return {
            statusCode: 200,
            body: res,
            isBase64Encoded: false            
        }
    })
    .catch(err => {
        return {
            statusCode: 400,
            body: err.message,
            isBase64Encoded: false            
        }
    })
    return res
}

main1().then(console.log)
main2().then(console.log)

【讨论】:

  • 我现在明白了!我的错误是在抛出错误后忘记捕捉这些错误。非常感谢!帮了大忙!
猜你喜欢
  • 2018-02-19
  • 1970-01-01
  • 1970-01-01
  • 2010-10-25
  • 2021-06-02
  • 2019-07-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多