Обработка ошибок пошаговой функции AWS для Go Lambda

# #go #aws-lambda #aws-serverless #aws-step-functions

Вопрос:

Я не могу найти подробное объяснение того, как определить сопоставитель условий ошибок в функции шага на основе ошибки, возвращенной обработчиком Go.

Это handler стандартная функция Go, которая возвращает error значение, если она получает 503 от вышестоящей службы:

 func HandleHotelBookingRequest(ctx context.Context, booking HotelBookingRequest) (
    confirmation HotelBookingResponse, err error) {
    
    ...
        if statusCode == http.StatusServiceUnavailable {
            err = errors.New("TransientError")
        } else {

 

Я могу контролировать, что возвращает функция и как она форматирует строку; Я не могу найти никакой реальной информации о том, что использовать здесь (или в Catch предложении, если на то пошло), так что это соответствует приведенному выше:

       "Retry": [
        {
          "ErrorEquals": [
            "TransientError"
          ],
          "BackoffRate": 1,
          "IntervalSeconds": 1,
          "MaxAttempts": 3,
          "Comment": "Retry for Transient Errors (503)"
        }
      ]
 

Когда я тестирую Лямбду в консоли, это то, что я получаю (как и ожидалось), когда восходящий поток возвращает 503:

 {
  "errorMessage": "TransientError",
  "errorType": "errorString"
}
 

И у меня сложилось отчетливое впечатление (но я не совсем уверен, как это подтвердить), что если я изменюсь на:

           "ErrorEquals": [
            "errorString"
          ],
 

это Retry работает (по крайней мере, просматривая журналы CloudWatch, я вижу transient error , что s регистрируется, но функция шага в конечном итоге выполняется успешно).

Я не могу найти много документации по этому вопросу, но:

  1. можно ли было бы сопоставить фактическое сообщение об ошибке (я видел, что шлюз API позволяет это делать, используя регулярное выражение);
  2. если это невозможно, должен ли я возвращать другой «тип ошибки» вместо error

Заранее спасибо!

Ответ №1:

Наконец-то разгадал загадку; в конце концов, это было тривиально и довольно идентично подходу JavaScript (который (а) дал мне подсказку и (б) широко документирован в примерах); однако, поскольку я нигде не смог найти конкретный ответ (в AWS -обширной, хорошей, подробной документации, Google, здесь) Я публикую его здесь для дальнейшего использования.

TL;DR — определите свою собственную реализацию error интерфейса и верните объект этого типа вместо стандарта bog fmt.Error() , затем используйте имя типа в ErrorEquals предложении.

Очень простой пример реализации показан в этой сути.

Чтобы проверить это, я создал ErrorStateMachine (определение JSON в той же сути) и выбрал другой уловитель в зависимости от ErrorEquals типа:

         {
          "ErrorEquals": [
            "HandlerError"
          ],
          "Next": "Handler Error"
        }
 

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

Что, я думаю, сбило меня с толку, так это то, что я относительный новичок, когда дело доходит до работы, и я не понимал, что errorString это фактический тип error интерфейса, возвращаемого errors.New() методом, который используется внутри fmt.Errorf() :

 // in errors/errors.go

// errorString is a trivial implementation of error.
type errorString struct {
    s string
}
 

Я наивно предположил, что это было просто то, что AWS назвал.

Интересный поворот (который на самом деле не идеален) заключается в том, что фактическое сообщение об ошибке «завернуто» в вывод функции шага и может быть немного громоздким для анализа на последующих шагах:

 {
  "Error": "HandlerError",
  "Cause": "{"errorMessage":"error from a failed handler","errorType":"HandlerError"}"
}
 

Безусловно, было бы намного удобнее для разработчиков, если бы фактическое сообщение об ошибке (сгенерированное Error() ) отправлялось прямо в Cause поле.

Надеюсь, другие найдут это полезным и им не придется тратить на это время, как мне.