Home > OS >  How can I pass the input and error of my failing task to a fallback task using AWS Step Functions?
How can I pass the input and error of my failing task to a fallback task using AWS Step Functions?

Time:10-13

I'm trying to add some error handling to my step functions state machine and I've been having issues on a specific scenario, for example if I have a fail on a step I have a catch to send it to another function, but in that function I need to perform logic using the last step input data (the one that failed), however, I just receive an error, is there a way to pass the input data with the error as well?

Send Notification:
        Type: Task
        Resource: !GetAtt CommunicationSendCertifiedEmail.Arn
        Retry:
          - ErrorEquals:
            - TierOneError
            IntervalSeconds: 2
            MaxAttempts: 9
            BackoffRate: 1.5
          - ErrorEquals:
            - TierTwoError
            IntervalSeconds: 4
            MaxAttempts: 6
            BackoffRate: 1.5
          - ErrorEquals:
            - TierThreeError
            IntervalSeconds: 4
            MaxAttempts: 3
            BackoffRate: 2
          - ErrorEquals:
            - States.Timeout
            - States.Runtime
            - States.TaskFailed
            - Lambda.ServiceException
            IntervalSeconds: 4
            MaxAttempts: 3
            BackoffRate: 2
        Catch:
          - ErrorEquals:
            - States.ALL
            Next: Send Email Notification

on that "Send email notification" is where I need the input before the execution failed, but as I stated before I just get something like this:

{
  "Error": "Error",
  "Cause": "{\"errorType\":\"Error\",\"errorMessage\":...
}

I would like to get something like this:

{
  "data": "{...}",
  "Error": "Error",
  "Cause": "{\"errorType\":\"Error\",\"errorMessage\":...
}

Any ideas? Is it even possible?

CodePudding user response:

Use enter image description here


Specify a ResultPath for where the error output should go.

That way, it'll take the state output (which is an error in this case) and includes it with the input.

This won't overwrite all of the state input, which allows you to preserve the input.

Here's an example - this is what you want:

enter image description here


Try:

Catch:
  - ErrorEquals:
    - States.ALL
    Next: Send Email Notification
    ResultPath: $.error

If the previous Catch statement catches an error, it'll include the error output in an error node within the state input (the node is called error as we specified the path to be $.error).

This acts like the second figure above.


For example, if the state input for Send Notification is:

{
    "foo": "bar"
}

The state output that is sent to Send Email Notification, when catching an error, will be the following.

{
  "foo": "bar",
  "error": {
    "Error": "Error here"
  }
}

It may also be the below, as the object also usually contains the Cause field (as it does in your case). This field's value is a human-readable description of the error.

{
  "foo": "bar",
  "error": {
    "Error": "Error here",
    "Cause": "{\"errorType\":\"Error\",\"errorMessage\"
  }
}

Important note:

Choose a unique name for the error node depending on your input data as I've just used error for demonstration purposes.

If the node specified already exists e.g. you already have a field with the name error, the ResultPath will update & overwrites the node with your error output which isn't what you want.

A picture is worth a thousand words, so this is the 3rd path that is possible using a ResultPath (again, this is not what you want):

enter image description here


If you're curious, the last path possible (which isn't related to the question but good to know) is discarding the state result (which you need, hence why it isn't related) and keeping the original input.

Setting ResultPath to null achieves this, as outlined here.

  • Related