1

I'm working on a project with this workflow : an API Gateway (defined using open api) trigger a Step function from AWS. There is 2 steps, and in case of errors, there is a catch block in the State machine definition.

But I'm facing an issue with error handling. Even if my code throw an error (400 for example), my Postman (or other REST API testing tools) respond with a 200. And I would like to have a 500/400...

Here is the code :

Step function definiton as serverless

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"

and here is my 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

With this configuration I always pass in 200 statusCode case. But I have an error as body response since my code is throwing an error.

Did I miss something?

1 Answer 1

6

After a quick scan of your code I think you've missed two things.

Firstly, in the step function, your error state is of type "Fail" which means that the step function stops and nothing is returned to the API Gateway so all it can do is report the 200 (or the default status code set in the open api definition).

To get a non-standard status code back to the client, you have to return something from the step function and then use a data transformation in the API Gateway to override the status function.

So your fallback state should be of type "Pass" and output the error information, including a status code.

And then you detect that status code in the Gateway and use it to override the response status code using a velocity template.

Take a look at https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-override-request-response-parameters.html for an example.

Sign up to request clarification or add additional context in comments.

1 Comment

Hey mate, thank you for the answer. The pass is working well with velocity template transformation ! Thank you for the help, I accept the answer

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.