在无服务器的lambda中返回HTTP错误代码的正确方法是什么?

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

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

我现在使用的模式( 它工作! )是:

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 

在这个地方我find了下面的解释: 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已经被弃用,不应该被使用(尽pipe它仍然有效)。

什么是使用callback(error)

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

这种error handling方式特定于API网关。

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

在API网关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网关触发的Lambda。

例如,如果您有SNS触发的Lambda,则可以返回callback('Any error message here') ,并且会让SNS知道它失败,因此SNS可以重试调用。

Interesting Posts