как получить доступ к информации об ошибке в пошаговой функции из предыдущей функции в состоянии захвата

Мне интересно, как получить доступ к причине моего пользовательского исключения, возникшего внутри моей лямбда-функции. Мне нужно получить к нему доступ в конце моего рабочего процесса Step Functions, как показано ниже.

На приведенной ниже диаграмме показан пример неудачного выполнения. Ошибка (объект error-info со своими собственными разделами Error и Cause) обнаружена в выводе ParseTextractOutput, но мне интересно, как получить к ней доступ в OutputNotFound, как показано ниже.

Диаграмма ступенчатых функций

введите здесь описание изображения

Выход

Выход ParseTextractOutput

{
  "event"...
  "error-info": {
    "Error": "OutputNotFoundException",
    "Cause": "{\"errorMessage\": \"Contents of Textracted file: {...}}"
    }
  }
}

Я хотел бы как-то получить доступ к этим данным в этих полях (определения Step Functions):

...
  "States": {
    "OutputNotFound": {
      "Type": "Fail",
      "Error": "<useful stuff here, like $.error-info.Error or something>",
      "Cause": "<useful stuff here, like $.error-info.Cause or something>"
    },
...
    "ParseTextractOutput": {
      "Type": "Task",
      "Resource": "functionARN",
      "Catch": [
        {
          "ErrorEquals": ["OutputNotFoundException"],
          "ResultPath": "$.error-info",
          "Next": "OutputNotFound"
        }
      ],
      "End": true
    }

Код Python

Вот соответствующий код для функции ParseTextractOutput.

class OutputNotFoundException(Exception):
  pass

...

try:
  blocks = data['Blocks']
except KeyError as e:
  raise OutputNotFoundException('Contents of Textracted file: {}'.format(data))

person ChumiestBucket    schedule 21.05.2019    source источник
comment
Вы не можете на самом деле. Состояние Fail принимает только поля Type и Comments. Поскольку вам нужно InputPath для доступа к переменным из предыдущего состояния. Вы можете найти обходной путь, создав состояние Choice после ParseTextractOutput на основе результата, который вы можете либо перейти в состояние Fail, либо в состояние Succeed.   -  person frosty    schedule 21.08.2020


Ответы (1)


На данный момент (с текущей версией https://states-language.net/spec.html) Fail.Error и Fail.Cause не могут быть динамическими. Входные данные, которые передаются в состояние Fail, игнорируются, а строки исправления используются для ошибки и причины.

Мы можем рассматривать Fail как точку выполнения, чтобы объявить сообщение об исправлении, указать конец выполнения с ошибкой и выйти.

Это означает, что любая обработка должна быть выполнена до этих точек объявления. Как упоминал @frosty в комментариях, состояние Choice может быть полезным.

Альтернатива 1: использование выбора

Вот пример:

Конечный автомат с выбором перед состояниями сбоя

Допустим, у меня есть этот код Python в моей лямбда-функции:

class OutputNotFoundException(Exception):
  pass



def lambda_handler(event, context):
    raise OutputNotFoundException('Error message A')

Когда функция вернется, вывод будет JSON следующим образом:

{
  "Error": "OutputNotFoundException",
  "Cause": "{\"errorMessage\":\"Error message A\",\"errorType\":\"OutputNotFoundException\",\"stackTrace\":[\"...\\n\"]}"
}

Обратите внимание, что Cause — это еще один JSON, закодированный строкой. Мы можем преобразовать OutputNotFound в Pass и использовать встроенную функцию StringToJson() для преобразования закодированной строки в обычный JSON для упрощения обработки в дальнейшем:

    "OutputNotFound": {
      "Type": "Pass",
      "Parameters": {
        "details.$": "States.StringToJson($.Cause)"
      },
      "Next": "Error message?"
    },

Теперь у нас есть такой вывод:

{
  "details": {
    "errorMessage": "Error message A",
    "errorType": "OutputNotFoundException",
    "stackTrace": ["...\n"]
  }
}

Следующим состоянием будет Choice, которое просматривает $.details.errorMessage, чтобы определить правильное состояние Fail:

    "Error message?": {
      "Type": "Choice",
      "Choices": [
        {
          "Variable": "$.details.errorMessage",
          "StringEquals": "Error message A",
          "Next": "Error A"
        },
        {
          "Variable": "$.details.errorMessage",
          "StringEquals": "Error message B",
          "Next": "Error B"
        }
      ],
      "Default": "Unknown Error"
    },

Каждый выбор теперь указывает на нормальное состояние Fail для объявления строки исправления:

    "Error A": {
      "Type": "Fail",
      "Error": "OutputNotFoundException",
      "Cause": "OutputNotFoundException of type A happened"
    },

Альтернатива 2: завершить с пропуском

Если вы намерены получить точное сообщение об ошибке в качестве вывода вашего выполнения для последующей регистрации/обработки, одним из способов может быть выход из состояния Pass:

    "OutputNotFound": {
      "Type": "Pass",
      "Parameters": {
        "details.$": "States.StringToJson($.Cause)",
        "isError": true
      },
      "End": true
    }

Недостатком этого решения, конечно, является то, что выполнение завершается с успешным статусом, и нам нужно обработать вывод, чтобы обнаружить ошибку (отсюда и дополнительное поле isError выше).

person el_shayan    schedule 05.11.2020