在无服务器lambda

时间:2017-10-11 13:31:59

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

我有一个用Node.JS编写的无服务器lambda函数。

返回错误代码的最佳/正确方法是什么?

我现在使用的模式(并且有效!)是:

module.exports.endpoint = (event, context, callback) => {
    const response = {
        statusCode: 404,
        body: JSON.stringify({ message: 'Hello World!' })
    };
    callback(null, response);
}

当我拨打电话时,例如从POSTMAN,到我的终端,我得到:

Status: 404 Not Found 正是我期待的

此外,在日志中我可以看到:

Serverless: GET / (λ: get)
Serverless: [404] {"statusCode":404,"body":"{\"message\":\"Hello World!\"}"}

效果很好。

困扰我的是我将null作为错误传递给我。看一些其他教程/示例,我发现了以下模式:

https://aws.amazon.com/blogs/compute/error-handling-patterns-in-amazon-api-gateway-and-aws-lambda/

https://serverless.com/framework/docs/providers/aws/events/apigateway/

callback ("the sky is falling!");

callback("[BadRequest] Validation error: Missing field 'name'");

callback("[404] Not Found");

callback(new Error('[404] Not found'));

callback(JSON.stringify(myErrorObj));

所有这些都非常有意义,您可以指定HTTP状态代码 - 但我最终获得的是HTTP状态代码200。当我查看日志时,我可以看到错误是在200:

之后
Serverless: GET / (λ: get)
Serverless: Failure: the sky is falling!
Serverless: Replying 200

Serverless: GET / (λ: get)
Serverless: Failure: [BadRequest] Validation error: Missing field 'name'
Serverless: Replying 200

Serverless: GET / (λ: get)
Serverless: Failure: [404] Not Found
Serverless: Replying 200

Serverless: GET / (λ: get)
Serverless: Failure: [404] Not found
Serverless: Replying 200

Serverless: GET / (λ: get)
Serverless: Failure: {"errorType":"InternalServerError","httpStatus":500,"message":"An unknown error has occurred. Please try again."}
Serverless: Replying 200

在这个地方,我发现了以下解释: https://github.com/serverless/serverless/issues/4119

  

如果你想在这种情况下回复HTTP错误,你必须这样做   将HTTP错误编码为成功的Lambda响应

以下示例:

Sample 403:
callback(null, { statusCode: 403, body: "Forbidden", headers: { "Content-Type": "text/plain" } });
Sample 404:
callback(null, { statusCode: 400 });

所以这基本上和我一样。为了完整起见,我可以补充一点,还有很多使用context.fail(result)context.succeed(result)的示例 - 但我收集的内容context已被弃用且不应该是使用过(即使它仍然有效)。

使用callback(error)有什么意义?

1 个答案:

答案 0 :(得分:5)

  

如果您想在这种情况下使用HTTP错误进行响应,则必须将HTTP错误编码为成功的Lambda响应

这种错误处理方式特定于API网关。

就像在传统的Node web服务器(例如express)中一样,你可以使用`throw new Error('Invalid Payload')抛出任何错误,而中间件通常会将其转换为具有正确响应状态的HTTP响应。

在API Gateway Lambda中,可以这样编写......

function createResponse(status, body) {
  return {
    headers: {
      'Access-Control-Allow-Origin': '*',
    }
    statusCode: status,
    body: JSON.stringify(body)
  }
}

module.exports.endpoint = (event, context, callback) => {
    try {
      return callback(null, createResponse(200, processEvent(event)))
    } except (e)
      console.error(e)

      return callback(null, createResponse(500, {
        error: 'Internal Server Error',
      }))
}

基本上,这是一个处理错误。 lambda函数成功但请求失败(可能是400,404或500)。

您应该始终处理错误,否则如果您的处理程序崩溃(由于运行时错误或语法错误或任何不正确的错误),您的用户将得到意外的响应(500或502)我想要。

话虽如此,请记住Lambda不仅用于API网关。 callback(error)用于非API网关触发的Lambdas。

例如,如果你有一个SNS触发的Lambda,你可以返回callback('Any error message here'),它会让SNS知道它失败了,所以SNS可以重试调用。