使用同步 StepFunctions 处理 API 网关中的错误

Handling error in API Gateway with Synchronous StepFunctions

我正在使用此工作流处理一个项目:API 网关(使用 open api 定义)从 AWS 触发一个 Step 函数。有2个步骤,如果出错,状态机定义中有一个catch块。

但我遇到了错误处理问题。即使我的代码抛出错误(例如 400),我的 Postman(或其他 REST API 测试工具)也会以 200 响应。我想要一个 500/400...

这是代码:

步进函数定义为无服务器

stepFunctions:
  stateMachines:
    PostPayment:
      name: testfunction
      type: EXPRESS
      definition:
        Comment: 'test'
        StartAt: Function1
        States:
          Function1:
            Type: Task
            Resource: !GetAtt Function1.Arn
            Catch:
              - ErrorEquals: ['HandledError']
                Next: Fallback
            Next: Function2
          Function2:
            Type: Task
            Resource: !GetAtt Function2.Arn
            Catch:
              - ErrorEquals: ['HandledError']
                Next: Fallback
            End: true
          Fallback:
            Type: Fail
            Cause: "Error occured",
            Error: "Error"

这是我的 openapi yml

x-amazon-apigateway-request-validator: all
x-amazon-apigateway-integration:
  requestParameters:
    integration.request.path.id: method.request.path.id
  requestTemplates:
    application/json:
      Fn::Sub: |-
        {
          "input": "{\"id\": \"$input.params().path.get('id')\"}",
          "stateMachineArn": "<ARN>"
        }
  httpMethod: POST
  type: aws
  credentials: !GetAtt ApiGatewayExecutionRole.Arn
  uri: !GetAtt StartSyncExecution.Arn
  responses:
    "200":
      statusCode: 200
      responseTemplates:
        application/json: $util.parseJson($util.parseJson($input.body).output).body
    "401":
      statusCode: 401
      responseTemplates:
        application/json: $util.parseJson($util.parseJson($input.body).cause).errorMessage
    "400":
      statusCode: 400
      responseTemplates:
        application/json: $util.parseJson($util.parseJson($input.body).cause).errorMessage
    "404":
      statusCode: 404
      responseTemplates:
        application/json: $util.parseJson($util.parseJson($input.body).cause).errorMessage
    "500":
      statusCode: 500
      responseTemplates:
        application/json: $util.parseJson($util.parseJson($input.body).cause).errorMessage

使用这个配置,我总是传入 200 statusCode 的情况。但是我的 body 响应出错,因为我的代码抛出错误。

我是不是漏掉了什么?

快速浏览您的代码后,我认为您遗漏了两件事。

首先,在 step 函数中,您的错误状态是“失败”类型,这意味着 step 函数停止并且没有任何内容 returned 到 API 网关,因此它可以做的一切报告 200(或在打开 api 定义中设置的默认状态代码)。

要将非标准状态代码返回给客户端,您必须 return 来自步骤函数的内容,然后在 API 网关中使用数据转换来覆盖状态函数.

所以你的回退状态应该是“通过”类型并输出错误信息,包括状态代码。

然后您在网关中检测到该状态代码,并使用速度模板使用它来覆盖响应状态代码。

看一下 https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-override-request-response-parameters.html 的例子。