在无服务器的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可以重试调用。