4

class BadRequest(Exception): pass的 Lambda 函数中有。

我想让raise BadRequest("Invalid request params")API 返回一个状态码为 400 和正文{ "message": "Invalid request params" }(或等效项)的响应。

然而,简单地这样做会返回一个状态码为 200(哦,不!)和正文的响应

{
    "errorMessage": "Invalid request params",
    "errorType": "BadRequest",
    "stackTrace": <my application code that the user shouldnt see>
}

在网上搜索后,似乎我有3个选择:

1)chalice

2)使用集成响应和方法响应将该错误解析为更好的响应。当我抛出异常时,我会喜欢正则表达式[BadRequest].*并插入一个前缀(不是很优雅的 IMO)。

3) 使用Step Functions创建 API 的有状态表示。这似乎有点乏味,因为我需要学习 ASL,而且我不认识任何聋人。-.-

-.-亚马逊国家语言


我应该去哪个兔子洞,为什么?

4

4 回答 4

1

3年后我回到这个问题来描述我今天是如何解决这个问题的。我使用无服务器框架来部署我的 lambda 函数和 API 网关。

我使用一个装饰器来捕获异常并返回一个有效负载。例如,这里是一个成功的请求、一个预期的异常和一个意外的异常。

def my_successful_request(event, context):
    return {
        "statusCode": 200,
        "body": json.dumps({"success": True})
    }


def handle_exceptions(f):
    def deco(*args, **kwargs):
        try:
            return f(*args, **kwargs)
        except BadRequest as e:
            print(e)
            return {"statusCode": 400, "body": json.dumps({"message": str(e)})}
        except Exception as e:
            print(e)
            return {"statusCode": 500, "body": json.dumps({"message": "unexpected error"})}
    return deco

@handle_exceptions
def my_expected_error_request(event, context):
    raise BadRequest("This function raises a BadRequest with a 400 status code that should be sent to the user. The end user can read this text.")

@handle_exceptions
def my_unexpected_error_request(event, context):
    raise Exception("Uh oh. I didn't expect this. A 500 error with an obfuscated message is raised. The end user cannot read this text.")

这种模式使 API 很容易返回适当的错误消息和状态代码。我在这个handle_exceptions实现中有非常基本的日志记录,但是您可以获得非常详细的消息,f.__name__以了解错误的 Lambda 函数和回溯模块以了解异常的来源。所有这些错误管理对 API 用户完全隐藏。

于 2020-08-13T17:14:13.573 回答
0

Chalice使使用 Lambda 和 API Gateway 实现 REST API 变得非常简单,包括将引发的异常转换为响应。对于您的特定情况,您会引发如下异常:

import chalice
app = chalice.Chalice(app_name='your-app')
app.debug = True  # Includes stack trace in response. Set to False for production.

@app.route('/api', methods=['GET'])
def your_api():
    raise chalice.BadRequestError("Your error message")

在 GitHub 上有一个完整的 REST API 示例,它使用 Chalice 和 Lambda 和 API Gateway:aws-doc-sdk-examples

于 2020-08-03T22:23:17.737 回答
-1

您应该在 Lambda 中捕获异常并抛出自定义异常,如下所示。

public class LambdaFunctionHandler implements RequestHandler<String, String> {
  @Override
    public String handleRequest(String input, Context context) {

        Map<String, Object> errorPayload = new HashMap();
        errorPayload.put("errorType", "BadRequest");
        errorPayload.put("httpStatus", 400);
        errorPayload.put("requestId", context.getAwsRequestId());
        errorPayload.put("message", "Invalid request params " + stackstace);
        String message = new ObjectMapper().writeValueAsString(errorPayload);

        throw new RuntimeException(message);
    }
}

And then use Option 2  to map the error code .

Integration response:
Selection pattern: “.*"BadRequest".*”

Method response: 500

Mapping template:

#set ($errorMessageObj = $util.parseJson($input.path('$.errorMessage')))
{
  "type" : "$errorMessageObj.errorType",
  "message" : "$errorMessageObj.message",
  "request-id" : "$errorMessageObj.requestId"
}
于 2017-07-22T15:39:51.573 回答
-1

这是 AWS Step Functions 的完美用例。您需要设置 API Gateway 以直接调用您将创建的状态机。

这是上述状态机的 ASL:

{
  "Comment": "A state machine that executes my lambda function and catches the bad error.",
  "StartAt": "MyLambda",
  "States": {
    "MyLambda": {
      "Type": "Task",
      "Resource": "arn:aws:lambda:REGION:ACCOUNT_ID:function:FUNCTION_NAME",
      "Catch": [
        {
          "ErrorEquals": ["BadError"],
          "Next": "BadErrorFallback"
        }
      ],
      "End": true
    },
    "BadErrorFallback": {
      "Type": "Pass",
      "Result": "Put here whatever is the result that you want to return.",
      "End": true
    }
  }
}

这将运行您提供的 lambda 函数。如果 lambda 函数抛出 BadError,那么它将输出 BadErrorFallback 状态的结果。否则,它将输出 lambda 函数吐出的任何内容。

希望这可以帮助!

于 2017-11-03T22:49:08.633 回答