在无服务器Lambda中返回HTTP错误代码的正确方法是什么 [英] What's the correct way of returning HTTP error codes in serverless lambda

查看:161
本文介绍了在无服务器Lambda中返回HTTP错误代码的正确方法是什么的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a serverless lambda function written in Node.JS.

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

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

The pattern that I use right now (and it works!) is:

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

例如,当我从POSTMAN呼叫端点时,我得到:

When I make a call, for example from POSTMAN, to my endpoint I get:

Status: 404 Not Found正是我所期望的.

Status: 404 Not Found which is exactly what I'm expecting.

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

Moreover, in the logs I can see:

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

效果很好.

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

What bothers me is that I'm passing null as the error. Looking into a few other tutorials/examples I've found patterns like:

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:

All of them make perfect sense and you can specify HTTP Status Code - yet what I'm getting is HTTP Status Code 200 in the end. When I look at the logs I can see that the error was followed straight after with 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

In this place I've found following explanation: https://github.com/serverless/serverless/issues/4119

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

If you want to respond with HTTP errors in that case, you have to encode the HTTP error as successful Lambda response

以下面的示例为例:

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已被弃用,不应使用(即使它仍然可以使用) .

So that's basically the same way I've. For the sake of completeness, I can add that there is also a plenty of examples that uses context.fail(result) or context.succeed(result) - but from what I gathered context is deprecated and shouldn't be used (even though it still works).

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

推荐答案

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

If you want to respond with HTTP errors in that case, you have to encode the HTTP error as successful Lambda response

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

This way of error-handling is specific to API Gateway.

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

Just like in traditional Node web servers (e.g. express), you can throw any error using `throw new Error('Invalid Payload') and a middleware usually converts it into an HTTP response with the correct response status.

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

In API Gateway Lambda, this can be written like this...

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).

Basically, it's a handled error. The lambda function succeeded but the request failed (maybe 400, 404, or 500).

您应该始终处理错误,否则如果处理程序崩溃(由于运行时错误或语法错误或任何未处理的错误),您的用户将收到意外的响应(500或502),而您可能不会这样做.不想.

You should be handling errors always, or else if your handler crashes (due to a runtime error or syntax error or any unhandler error), your user will get an unexpected response (a 500 or a 502) which you probably don't want.

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

That being said, please remember that Lambda is not only used for API Gateway. callback(error) is used for non-API Gateway-triggered Lambdas.

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

For example, if you have an SNS-triggered Lambda, you can return callback('Any error message here') and it will let SNS know that it failed and so SNS can retry the invocation.

这篇关于在无服务器Lambda中返回HTTP错误代码的正确方法是什么的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆