Tratamento de erros no Step Functions - AWS Step Functions

As traduções são geradas por tradução automática. Em caso de conflito entre o conteúdo da tradução e da versão original em inglês, a versão em inglês prevalecerá.

Tratamento de erros no Step Functions

Todos os estados, exceto Pass e Wait, podem encontrar erros de runtime. Erros podem ocorrer por diversos motivos, como nos seguintes exemplos:

  • Problemas de definição da máquina de estado (por exemplo, nenhuma regra de correspondência em um estado Choice)

  • Falhas de tarefa (por exemplo, uma exceção em uma função AWS Lambda)

  • Problemas transitórios (por exemplo, eventos de partição de rede)

Por padrão, quando um estado relata um erro, o AWS Step Functions faz com que a execução falhe totalmente.

dica

Para implementar um exemplo de fluxo de trabalho que inclui tratamento de erros em sua Conta da AWS, consulte o Módulo 8 - Tratamento de erros do workshop do AWS Step Functions.

Nomes de erro

O Step Functions identifica os erros na Amazon States Language usando strings que fazem distinção de maiúsculas e minúsculas, conhecidas como nomes de erro. A Amazon States Language define um conjunto de strings integradas que nomeiam erros conhecidos, todos iniciados com o prefixo States..

States.ALL

Um curinga que corresponde a qualquer nome de erro conhecido.

nota

Esse tipo de erro não pode capturar o tipo de erro do terminal States.DataLimitExceeded e os tipos de erro de runtime. Para ver mais informações sobre esses tipos de regra, consulte States.DataLimitExceeded e States.Runtime.

States.DataLimitExceeded

O Step Functions relata uma exceção de States.DataLimitExceeded nas seguintes condições:

  • Quando a saída de um conector é maior que a cota de tamanho da carga.

  • Quando a saída de um estado é maior que a cota de tamanho da carga.

  • Após o processamento de Parameters, quando a entrada de um estado for maior que a cota de tamanho da carga.

Para ver mais informações sobre cotas, consulte Cotas.

nota

Esse é um erro de terminal que não pode ser detectado pelo tipo de erro States.ALL.

States.ExceedToleratedFailureThreshold

Um estado Map falhou porque o número de itens com falha excedeu o limite especificado na definição da máquina de estado. Para obter mais informações, consulte Limite de falha tolerado para o estado Mapa Distribuído.

States.HeartbeatTimeout

Um estado Task não conseguiu enviar uma pulsação por um período maior que o valor de HeartbeatSeconds.

nota

Esse erro só está disponível nos campos Catch e Retry.

States.IntrinsicFailure

Uma tentativa de invocar uma função intrínseca em um modelo de carga falhou.

States.ItemReaderFailed

Um estado Map falhou porque não foi possível ler a partir da fonte do item especificada no campo ItemReader. Para obter mais informações, consulte ItemReader.

States.NoChoiceMatched

Um estado Choice falhou em combinar a entrada com as condições definidas na Regra de escolha e uma transição Padrão não foi especificada.

States.ParameterPathFailure

Falha em uma tentativa de substituir um campo, dentro do campo Parameters de um estado, cujo nome termina em .$ usando um caminho.

States.Permissions

Um estado Task falhou porque tinha privilégios insuficientes para executar o código especificado.

States.ResultPathMatchFailure

O Step Functions não conseguiu aplicar o campo ResultPath de um estado à entrada que o estado recebeu.

States.ResultWriterFailed

Um estado Map falhou porque não conseguiu gravar os resultados no destino especificado no campo ResultWriter. Para obter mais informações, consulte ResultWriter.

States.Runtime

Uma execução falhou devido a alguma exceção que não pôde ser processada. Muitas vezes, isso é causado por erros em tempo de execução, como tentar aplicar InputPath ou OutputPath em uma carga útil JSON nula. Um erro States.Runtime não é recuperável e sempre fará com que a execução falhe. Uma nova tentativa ou captura em States.ALL não detectará erros States.Runtime.

States.TaskFailed

Um estado Task falhou durante a execução. Quando usado em uma nova tentativa ou captura, States.TaskFailed age como um curinga que corresponde a qualquer nome de erro conhecido, exceto States.Timeout.

States.Timeout

Um estado Task que executou por um tempo mais longo que o valor TimeoutSeconds ou não conseguiu enviar uma pulsação por um período maior que o valor HeartbeatSeconds.

Além disso, se uma máquina de estado for executada por mais tempo do que o valor de TimeoutSeconds especificado, a execução falhará com um erro States.Timeout.

Os estados podem relatar erros com outros nomes. No entanto, esses nomes de erro não podem começar com o prefixo States..

Como uma melhor prática, verifique se o seu código de produção pode lidar com exceções do serviço do AWS Lambda (Lambda.ServiceException e Lambda.SdkClientException). Para obter mais informações, consulte Lidar com exceções do serviço Lambda.

nota

Os erros não tratados no Lambda são relatados como Lambda.Unknown na saída do erro. Isso inclui erros de falta de memória e tempos limite de função. Você pode combinar com Lambda.Unknown, States.ALL ou States.TaskFailed para lidar com esses erros. Quando o Lambda atinge o número máximo de invocações, o erro é Lambda.TooManyRequestsException. Para obter mais informações sobre erros da função do Lambda, consulte Tratamento de erros e novas tentativas automáticas no Guia do desenvolvedor do AWS Lambda.

Nova tentativa após um erro

Os estados Task, Parallel e Map podem ter um campo denominado Retry, cujo valor deve ser uma matriz de objetos conhecidos como retriers. Um retrier individual representa determinado número de novas tentativas, geralmente em intervalos de tempo crescentes.

Quando um desses estados relata um erro e há um campo Retry, o Step Functions examina os recuperadores na ordem listada na matriz. Quando o nome do erro aparece no valor do campo ErrorEquals de um retrier, a máquina de estado faz novas tentativas conforme definido no campo Retry.

Se a execução do seu redriven executar novamente um estado Estado da tarefa, Paralelo ou Mapa inline, para o qual você definiu novas tentativas, a contagem de novas tentativas para esses estados será redefinida para 0 a fim de permitir o número máximo de tentativas realizadas em redrive Para uma execução redriven, você pode monitorar tentativas individuais desses estados usando o console. Para obter mais informações, consulte Repetir o comportamento das execuções redriven em Redriving execuções.

Um retrier contém os seguintes campos:

nota

As novas tentativas são tratadas como transições de estado. Para ver informações sobre como as transições de estado afetam o faturamento, consulte Preços do Step Functions.

ErrorEquals (obrigatório)

Uma matriz não vazia de strings que correspondem a Nomes de erro. Quando um estado relata um erro, o Step Functions examina os retriers. Quando o nome do erro é exibido na matriz, ele implementa a política de novas tentativas descrita nesse retrier.

IntervalSeconds (opcional)

Um inteiro positivo que representa o número de segundos antes da primeira tentativa nova (por padrão, 1). IntervalSeconds tem um valor máximo de 99999999.

MaxAttempts (opcional)

Um inteiro positivo que representa o número máximo de tentativas novas (por padrão, 3). Se o erro voltar a ocorrer mais vezes do que o especificado, as novas tentativas são interrompidas e o tratamento de erro normal é retomado. Um valor de 0 especifica que o erro nunca será repetido. MaxAttempts tem um valor máximo de 99999999.

BackoffRate (opcional)

O multiplicador pelo qual o intervalo de nova tentativa denotado por IntervalSeconds aumenta após cada nova tentativa. Por padrão, o valor de BackoffRate aumenta em 2.0.

Por exemplo, digamos que o seu IntervalSeconds é 3, MaxAttempts é 3 e BackoffRate é 2. A primeira nova tentativa ocorre três segundos após a ocorrência do erro. A segunda nova tentativa ocorre seis segundos após a primeira. Enquanto a terceira nova tentativa ocorre 12 segundos após a segunda.

MaxDelaySeconds (opcional)

Um número inteiro positivo que define o valor máximo, em segundos, até o qual um intervalo de nova tentativa pode aumentar. Esse campo é útil para ser usado com o campo BackoffRate. O valor especificado nesse campo limita os tempos de espera exponenciais resultantes do multiplicador da taxa de recuo aplicado a cada nova tentativa consecutiva. Você deve especificar um valor maior que 0 e menor que 31622401 para MaxDelaySeconds.

Se você não especificar esse valor, o Step Functions não limitará os tempos de espera entre as novas tentativas.

JitterStrategy (opcional)

Uma sequência de caracteres que determina se a oscilação deve ou não ser incluída nos tempos de espera entre novas tentativas consecutivas. A oscilação reduz as novas tentativas simultâneas distribuindo-as em um intervalo de atraso aleatório. Essa string aceita FULL ou NONE como seus valores. O valor padrão é NONE.

Por exemplo, digamos que você tenha definido MaxAttempts como 3, IntervalSeconds como 2 e BackoffRate como 2. A primeira nova tentativa ocorre dois segundos após a ocorrência do erro. A segunda nova tentativa ocorre quatro segundos após a primeira e a terceira ocorre oito segundos após a segunda. Se você definir JitterStrategy como FULL, o intervalo da primeira nova tentativa será randomizado entre 0 e 2 segundos, o intervalo da segunda nova repetição será randomizado entre 0 e 4 segundos e o intervalo da terceira nova tentativa será randomizado entre 0 e 8 segundos.

Exemplos do campo de nova tentativa

Essa seção inclui os seguintes exemplos do campo Retry.

dica

Para implementar um exemplo de fluxo de trabalho de tratamento de erros em sua Conta da AWS, consulte o módulo de Tratamento de erros do workshop do AWS Step Functions.

Exemplo 1 — Nova tentativa com BackOffRate

O exemplo a seguir de uma Retry faz duas novas tentativas, com a primeira ocorrendo após uma espera de três segundos. Com base no BackoffRate especificado, o Step Functions aumenta o intervalo entre cada nova tentativa até que o número máximo de novas tentativas seja atingido. No exemplo a seguir, a segunda nova tentativa começa depois de uma espera de três segundos após a primeira nova tentativa.

"Retry": [ { "ErrorEquals": [ "States.Timeout" ], "IntervalSeconds": 3, "MaxAttempts": 2, "BackoffRate": 1 } ]
Exemplo 2 — Nova tentativa com MaxDelaySeconds

O exemplo a seguir faz três novas tentativas e limita o tempo de espera resultante de BackoffRate para 5 segundos. A primeira nova tentativa ocorre após uma espera de três segundos. A segunda e a terceira novas tentativas ocorrem depois de uma espera de cinco segundos após a nova tentativa anterior, devido ao limite máximo de tempo de espera definido por MaxDelaySeconds.

"Retry": [ { "ErrorEquals": [ "States.Timeout" ], "IntervalSeconds": 3, "MaxAttempts": 3, "BackoffRate":2, "MaxDelaySeconds": 5, "JitterStrategy": "FULL" } ]

Sem MaxDelaySeconds, a segunda nova tentativa ocorreria seis segundos após a primeira e a terceira ocorreria 12 segundos após a segunda.

Exemplo 3 — Nova tentativa de todos os erros, exceto States.Timeout

O nome reservado States.ALL que aparece no campo ErrorEquals de um retrier é um curinga que corresponde a qualquer nome de erro. Ele deve aparecer sozinho na matriz ErrorEquals e também no último retrier na matriz Retry. O nome States.TaskFailed também atua como um curinga e corresponde a qualquer erro, exceto States.Timeout.

O segundo exemplo de um campo Retry faz nova tentativa em relação a qualquer erro, exceto States.Timeout.

"Retry": [ { "ErrorEquals": [ "States.Timeout" ], "MaxAttempts": 0 }, { "ErrorEquals": [ "States.ALL" ] } ]
Exemplo 4 — Cenário complexo de nova tentativa

Parâmetros de um retrier em todas as visitas ao retrier no contexto de uma única execução de estado.

Considere o seguinte estado Task.

"X": { "Type": "Task", "Resource": "arn:aws:states:us-east-1:123456789012:task:X", "Next": "Y", "Retry": [ { "ErrorEquals": [ "ErrorA", "ErrorB" ], "IntervalSeconds": 1, "BackoffRate": 2.0, "MaxAttempts": 2 }, { "ErrorEquals": [ "ErrorC" ], "IntervalSeconds": 5 } ], "Catch": [ { "ErrorEquals": [ "States.ALL" ], "Next": "Z" } ] }

Essa tarefa falha quatro vezes sucessivas, produzindo os seguintes nomes de erro: ErrorA, ErrorB, ErrorC e ErrorB. O seguinte ocorre em consequência disso:

  • Os dois primeiros erros correspondem ao primeiro retrier e provocam esperas de um e dois segundos.

  • O terceiro erro corresponde ao segundo retrier e provoca uma espera de cinco segundos.

  • O quarto erro também corresponde ao primeiro retrier. No entanto, ele já atingiu o máximo de duas novas tentativas (MaxAttempts) para esse erro específico. Portanto, esse retrier falha e a execução redireciona o fluxo de trabalho para o estado Z por meio do campo Catch.

Estados de fallback

Os estados Task, Map e Parallel podem ter um campo denominado Catch. O valor desse campo deve ser uma matriz de objetos, conhecidos como catchers.

Um catcher contém os campos a seguir.

ErrorEquals (obrigatório)

Uma matriz não vazia de strings que correspondem a nomes de erros, especificados exatamente como aparecem no campo do retrier de mesmo nome.

Next (obrigatório)

Uma string que deve corresponder exatamente a um dos nomes de estado da máquina de estado.

ResultPath (opcional)

Um caminho que determina qual entrada o catcher envia ao estado especificado no campo Next.

Quando um estado relata um erro e não existe nenhum campo Retry ou as novas tentativas não conseguem resolver o erro, o Step Functions examina os catchers na ordem listada na matriz. Quando o nome do erro é exibido no valor do campo ErrorEquals de um catcher, a máquina de estado muda para o estado denominado no campo Next.

O nome reservado States.ALL que aparece em um campo ErrorEquals do catcher é um curinga que corresponde a qualquer nome de erro. Ele deve aparecer sozinho na matriz ErrorEquals e também no último catcher na matriz Catch. O nome States.TaskFailed também atua como um curinga e corresponde a qualquer erro, exceto States.Timeout.

O exemplo a seguir de um campo Catch muda para o estado denominado RecoveryState quando uma função do Lambda gera uma exceção Java não tratada. Do contrário, o campo muda para o estado EndState.

"Catch": [ { "ErrorEquals": [ "java.lang.Exception" ], "ResultPath": "$.error-info", "Next": "RecoveryState" }, { "ErrorEquals": [ "States.ALL" ], "Next": "EndState" } ]
nota

Todo catcher pode especificar vários erros para tratamento.

Error output (Saída de erro)

Quando o Step Functions muda para o estado especificado em um nome de catch, o objeto normalmente contém o campo Cause. O valor desse campo é uma descrição de erro humanamente. Esse objeto é conhecido como saída de erro.

Neste exemplo, o primeiro catcher contém um campo ResultPath. Ele funciona de modo semelhante a um campo ResultPath em um nível superior do estado, o que resulta em duas possibilidades:

  • Ele pega os resultados da execução desse estado e substitui toda a entrada do estado ou uma parte dela.

  • Ele leva os resultados e os adiciona à entrada. No caso de um erro tratado por um catcher, o resultado da execução do estado é a saída de erro.

Assim, para o primeiro catcher do exemplo, o catcher adicionará a saída de erro à entrada como um campo chamado error-info se ainda não houver um campo com esse nome na entrada. Em seguida, o catcher envia toda a entrada para RecoveryState. Para o segundo catcher, a saída de erro substitui a entrada e o catcher envia somente a saída de erro para EndState.

nota

Se você não especificar o campo ResultPath, ele usará como padrão $, que seleciona e substitui a entrada completa.

Quando um estado tem os campos Retry e Catch, o Step Functions usa primeiro qualquer retrier apropriado. Se a política de nova tentativa não solucionar o erro, o Step Functions aplicará a transição correspondente do catcher.

Cargas de causa e integrações de serviços

Um catcher retorna uma carga de string como saída. Ao trabalhar com integrações de serviços, como Amazon Athena ou AWS CodeBuild, talvez você queira converter a string Cause em JSON. O exemplo a seguir de um estado Pass com funções intrínsecas mostra como converter uma string Cause em JSON.

"Handle escaped JSON with JSONtoString": { "Type": "Pass", "Parameters": { "Cause.$": "States.StringToJson($.Cause)" }, "Next": "Pass State with Pass Processing" },

Exemplos de máquina de estado que usam Nova tentativa e Detecção

As máquinas de estado definidas nos exemplos a seguir presumem que existem duas funções do Lambda: uma que sempre falha e uma que aguarda tempo suficiente para permitir que haja um tempo limite definido na máquina de estado.

Essa é uma definição de função do Lambda Node.js que sempre falha, retornando a mensagem error. Nos exemplos de máquina de estado a seguir, essa função do Lambda é denominada FailFunction. Para ver mais informações sobre a criação de uma função do Lambda, consulte a seção Etapa 1: criar uma função do Lambda.

exports.handler = (event, context, callback) => { callback("error"); };

Essa é uma definição de função do Lambda Node.js que hiberna por 10 segundos. Nos exemplos de máquina de estado a seguir, essa função do Lambda é denominada sleep10.

nota

Ao criar essa função do Lambda no console do Lambda, lembre-se de alterar o valor Tempo limite na seção Configurações avançadas de 3 segundos (padrão) para 11 segundos.

exports.handler = (event, context, callback) => { setTimeout(function(){ }, 11000); };

Tratamento de falhas usando novas tentativas

Essa máquina de estado usa um campo Retry para tentar novamente uma função que falha e gera o nome de erro HandledError. Duas novas tentativas dessa função são feitas com um recuo exponencial entre as novas tentativas.

{ "Comment": "A Hello World example of the Amazon States Language using an AWS Lambda function", "StartAt": "HelloWorld", "States": { "HelloWorld": { "Type": "Task", "Resource": "arn:aws:lambda:us-east-1:123456789012:function:FailFunction", "Retry": [ { "ErrorEquals": ["HandledError"], "IntervalSeconds": 1, "MaxAttempts": 2, "BackoffRate": 2.0 } ], "End": true } } }

Essa variante usa o código de erro predefinido States.TaskFailed, que corresponde a qualquer erro gerado por uma função do Lambda.

{ "Comment": "A Hello World example of the Amazon States Language using an AWS Lambda function", "StartAt": "HelloWorld", "States": { "HelloWorld": { "Type": "Task", "Resource": "arn:aws:lambda:us-east-1:123456789012:function:FailFunction", "Retry": [ { "ErrorEquals": ["States.TaskFailed"], "IntervalSeconds": 1, "MaxAttempts": 2, "BackoffRate": 2.0 } ], "End": true } } }
nota

Como uma prática recomendada, as tarefas que fazem referência a uma função do Lambda devem lidar com exceções do serviço Lambda. Para obter mais informações, consulte Lidar com exceções do serviço Lambda.

Tratamento de falhas usando detecção

Este exemplo usa um campo Catch. Quando uma função do Lambda gera um erro, o erro é detectado e a máquina de estado muda para o estado fallback.

{ "Comment": "A Hello World example of the Amazon States Language using an AWS Lambda function", "StartAt": "HelloWorld", "States": { "HelloWorld": { "Type": "Task", "Resource": "arn:aws:lambda:us-east-1:123456789012:function:FailFunction", "Catch": [ { "ErrorEquals": ["HandledError"], "Next": "fallback" } ], "End": true }, "fallback": { "Type": "Pass", "Result": "Hello, AWS Step Functions!", "End": true } } }

Essa variante usa o código de erro predefinido States.TaskFailed, que corresponde a qualquer erro gerado por uma função do Lambda.

{ "Comment": "A Hello World example of the Amazon States Language using an AWS Lambda function", "StartAt": "HelloWorld", "States": { "HelloWorld": { "Type": "Task", "Resource": "arn:aws:lambda:us-east-1:123456789012:function:FailFunction", "Catch": [ { "ErrorEquals": ["States.TaskFailed"], "Next": "fallback" } ], "End": true }, "fallback": { "Type": "Pass", "Result": "Hello, AWS Step Functions!", "End": true } } }

Tratamento de tempo limite usando novas tentativas

Essa máquina de estado usa um campo Retry para fazer uma nova tentativa do estado Task que atinge o tempo limite, com base no valor de tempo limite especificado em TimeoutSeconds. O Step Functions faz duas novas tentativas da invocação da função do Lambda nesse estado Task, com um recuo exponencial entre as novas tentativas.

{ "Comment": "A Hello World example of the Amazon States Language using an AWS Lambda function", "StartAt": "HelloWorld", "States": { "HelloWorld": { "Type": "Task", "Resource": "arn:aws:lambda:us-east-1:123456789012:function:sleep10", "TimeoutSeconds": 2, "Retry": [ { "ErrorEquals": ["States.Timeout"], "IntervalSeconds": 1, "MaxAttempts": 2, "BackoffRate": 2.0 } ], "End": true } } }

Tratamento de tempo limite usando detecção

Este exemplo usa um campo Catch. Quando ocorre um tempo limite, a máquina de estado muda para o estado fallback.

{ "Comment": "A Hello World example of the Amazon States Language using an AWS Lambda function", "StartAt": "HelloWorld", "States": { "HelloWorld": { "Type": "Task", "Resource": "arn:aws:lambda:us-east-1:123456789012:function:sleep10", "TimeoutSeconds": 2, "Catch": [ { "ErrorEquals": ["States.Timeout"], "Next": "fallback" } ], "End": true }, "fallback": { "Type": "Pass", "Result": "Hello, AWS Step Functions!", "End": true } } }
nota

Você pode preservar a entrada de estado e o erro usando ResultPath. Consulte Use ResultPath para incluir erro e entrada em um Catch.