Propogating error message through Fail state in aws Step Functions

Viewed 2709

I am using aws Step Functions to manage a workflow. I am using Fail states to handle errors within the workflow. I would like to propagate some of the json from the Step Function workflow so that a user can easily identify the source of their error. So for example, if the json input to a Fail state looked like this:

{
    "error": "some error text",
    "other_stuff": {...}
}

Then I would like to pull the source of the error. I have set up my Fail state like so:

FailState:
    Type: Fail
    Cause: States.Format($.error)
    Error: Failure Here

However, this simply produces the literal string States.Format($.error) as the Cause for the Fail state. How can I use aws states language and the Fail state to show the actual error as a part of the output of the Fail state? Any solution that can successfully propagate the error text from Step Input to Step Output for the Fail state would be sufficient to solve this problem.

3 Answers

If anyone else stumbles on this question, I contacted AWS support and this is what they told me:

"The ‘Cause’ and ‘Error’ fields in this state only accept the string type values. This is why you are getting the literal string as a response. However, the good news is that, we already have an existing feature request, pending with Step Functions Development team, to implement a feature for sending JSON Path(like $.error) into the Fail state."

So for some reason AWS step functions does not allow you to pass dynamic error messages. They did offer some workarounds such as changing the failure state to success and propagating the error message that way, or creating an sns topic in the case of statemachine failure to post to. I personally just updated the status polling API to grab the state at index [-2] to propagate the error to the user. In any case, to use this functionality currently some workaround should be employed, and hopefully AWS can get this feature out quickly.

I was able to achieve something close to a desired behavior by creating a "Fail-Me" Lambda that fails with an unhandled exception, dynamically choosing exception class based on the Error and Cause provided as its payload. If "Error" was a name of a built-in exception class it uses it, otherwise it creates its own class.

In State Machine, use an Invoke Lambda state calling this "Fail-Me" lambda with no retrier and no catcher.

import inspect, sys

# Expected payload (event), example:
#      {
#           "Error":"RuntimeError",
#           "Cause":"No Cause"
#       }

def lambda_handler(event, context):
    
    ErrorType  = event.get("Error") or ""
    ErrorCause = event.get("Cause") or ""


    if not ErrorType.isidentifier():
        ErrorCause = "{}: {}".format(ErrorType, ErrorCause)
        ErrorType = "OtherError"

    DynamicExceptionClass = type(ErrorType, (BaseException,), {})

    for name, obj in inspect.getmembers(sys.modules["builtins"]):
        if inspect.isclass(obj) and issubclass (obj, BaseException):
            if name==ErrorType:              #ErrorType is an existing built-in exception - use it
                raise obj(ErrorCause)


    #Create our own dynamic class and raise it

    DynamicExceptionClass = type(ErrorType, (BaseException,), {})

    raise DynamicExceptionClass(ErrorCause)

I too want to use a JSON path in a Fail state to dynamically set the Cause and Error fields. In my case, I have a known set of errors so for each one I created a separate Fail state. Each one of those fail states corresponded with a catch object where Next is set to the appropriate fail state.

{
  "TaskState": {
    "Type": "Task",
    ...
    "Catch": [
      {
         "ErrorEquals": ["ErrorA"],
         "Next": "FailureA"
      },
      {
         "ErrorEquals": ["ErrorB"],
         "Next": "FailureB"
      }
    ]
  },
  "FailureA": {
    "Type": "Fail",
    "Error": "FailureA",
    "Cause": "This failed because of A"
  },
  "FailureB": {
    "Type": "Fail",
    "Error": "FailureB",
    "Cause": "This failed because of B"
  }
}
Related