AWS Step Functions
開発者ガイド

エラー処理

状態でランタイムエラーが発生することがあります。エラーはさまざまな理由で発生します。

  • ステートマシンの定義の問題 (たとえば、Choice 状態に一致するルールがない)。

  • タスクの失敗 (たとえば、Lambda 関数の例外)。

  • 一時的な問題 (たとえば、ネットワークパーティションイベント)。

デフォルトでは、状態でエラーが報告されると、AWS Step Functions の実行全体が失敗します。

エラー名

Step Functions は大文字と小文字を区別する文字列を使用して Amazon ステートメント言語 でエラーを識別します。これをエラー名といいます。Amazon ステートメント言語 は、よく知られているエラー名付ける一連の組み込み文字列を定義します。すべて States. というプレフィックスが付いています。

States.ALL

すべての既知のエラー名に一致するワイルドカード。

States.Timeout

TimeoutSeconds 値より長時間実行されたか、HeartbeatSeconds 値より長い間隔ハートビートの送信に失敗した Task 状態。

States.TaskFailed

実行中に失敗した Task 状態。

States.Permissions

指定されたコードの実行に必要な特権が足りないため失敗した Task 状態。

状態は別の名前でエラーを報告することがあります。ただし、これらは States. プレフィックスで始まるとは限りません。

ベストプラクティスとして、本番稼働用コードが AWS Lambda サービス例外 (Lambda.ServiceException および Lambda.SdkclientException) を処理できることを確認します。詳細については、「Lambda サービス例外の処理」を参照してください。

注記

Lambda で処理されないエラーは、エラー出力で Lambda.Unknown と表示されます。これには、メモリ不足エラー、関数のタイムアウト、同時 Lambda 呼び出しの制限などがあります。これらのエラーを処理するには、Lambda.UnknownStates.ALL、または States.TaskFailed で一致できます。Lambda が呼び出しの制限に達した場合のエラーは Lambda.TooManyRequestsException になります。Lambda の Handled および Unhandled エラーの詳細については、AWS Lambda Developer Guideの「FunctionError」を参照してください。

エラー後の再試行

Task および Parallel 状態は Retry という名前のフィールドを持つことができます。その値は retriers と呼ばれるオブジェクトの配列にする必要があります。個々の retrier は特定回数の再試行を表し、通常は時間間隔が増加していきます。

注記

再試行は状態遷移として扱われます。状態遷移が請求に与える影響の詳細については、「Step Functions 料金表」を参照してください。

retrier には以下のフィールドがあります。

ErrorEquals (必須)

エラー名に一致する空でない文字列の配列です。状態がエラーを報告すると、Step Functions は retriers 全体をスキャンします。エラー名がこの配列に表示されている場合、この retrier に記述されている再試行ポリシーを実装します。

IntervalSeconds(オプション)

最初の再試行前の秒数を表す整数 (デフォルトは 1)。

MaxAttempts(オプション)

再試行の最大回数を表す正の整数 (デフォルトでは 3)。エラーが指定された回数を超えて再発する場合は、再試行が停止され通常のエラー処理が再開されます。値 0 を指定すると、エラーは再試行されません。

BackoffRate(オプション)

各試行間で再試行間隔が増加する乗数 (デフォルトでは 2.0)。

この Retry の例では、2 回の再試行を、3 秒および 4.5 秒間待機した後に行います。

"Retry": [ { "ErrorEquals": [ "States.Timeout" ], "IntervalSeconds": 3, "MaxAttempts": 2, "BackoffRate": 1.5 } ]

retrier の ErrorEquals フィールドにあらかじめ表示される名前 States.ALL は、すべてのエラー名に一致するワイルドカードです。ErrorEquals 配列では単独で表示される必要があり、Retry 配列では最後の retrier に表示される必要があります。

この Retry フィールドの例では、States.Timeout を除くすべてのエラーを再試行します。

"Retry": [ { "ErrorEquals": [ "States.Timeout" ], "MaxAttempts": 0 }, { "ErrorEquals": [ "States.ALL" ] } ]

複雑な再試行シナリオ

retrier のパラメータは、単一状態実行のコンテキストの retrier に対するすべてのアクセスに適用されます。

次の 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" } ] }

このタスクは 5 回連続で失敗し、エラー名 ErrorAErrorBErrorCErrorB、および ErrorB を出力します。結果として以下が発生します。

  • 最初の 2 つのエラーが最初の retrier に一致し、1 秒および 2 秒の待機が発生します。

  • 3 番目のエラーが 2 番目の retrier に一致し、5 秒の待機が発生します。

  • 4 番目のエラーが 1 番目の retrier に一致し、4 秒の待機が発生します。

  • 5 番目のエラーも最初の retrier に一致します。ただし、その特定のエラー (ErrorB) における再試行の制限 (MaxAttempts) である 2 回にすでに達しているため、実行は失敗し、Catch フィールドを介して Z 状態にリダイレクトされます。

Fallback 状態

Task および Parallel 状態は Catch というフィールドを持つことができます。このフィールドの値は、catchers と言われるオブジェクトの配列である必要があります。

catcher には以下のフィールドがあります。

ErrorEquals (必須)

同じ名前の retrier フィールドで指定されたエラー名と正確に一致する空ではない文字列。

Next (必須)

ステートマシンの状態名のいずれかに正確に一致する必要がある文字列。

ResultPath(オプション)

Next フィールドに指定された状態に対して送信される入力を決定するパス

状態がエラーを報告し、Retry フィールドがないか再試行でエラーが解決できなかった場合、Step Functions は配列にリストされた順序で catcher をスキャンします。エラー名が catcher の ErrorEquals フィールドの値に表示される場合、ステートマシンは Next フィールドに名前がある状態に移行します。

catcher の ErrorEquals フィールドにあらかじめ表示される名前 States.ALL は、すべてのエラー名に一致するワイルドカードです。ErrorEquals 配列では単独で表示される必要があり、Catch 配列では最後の catcher に表示される必要があります。

次の Catch フィールドの例では、Lambda 関数が処理されない Java 例外を出力した場合に RecoveryState という名前の状態に移行します。それ以外の場合は、フィールドは EndState 状態に移行します。

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

注記

各 catcher には処理するエラーを複数指定できます。

エラー出力

Step Functions が catch 名に指定された状態に移行する場合、オブジェクトには通常 Cause というフィールドが含まれます。このフィールドの値は人間が読んで理解できるエラーの説明です。このオブジェクトはエラー出力といいます。

この例では、最初の catcher に ResultPath フィールドが含まれています。これは状態の最上位の ResultPath フィールドに似た動作を行い、次のいずれかの結果になります。

  • 状態を実行した結果を取得して、状態の入力の一部 (または状態の入力のすべて) を上書きします。

  • 結果を取得して入力に追加します。catcher によって処理されたエラーの場合、状態の実行結果はエラー出力です。

したがって、この例では、最初の catcher ではエラー出力が error-info という名前のフィールドとして入力に追加されます (入力にこの名前のフィールドが存在しない場合)。次に、入力全体が RecoveryState に送信されます。2 番目 catcher では、エラー出力によって入力が上書きされ、エラー出力のみが EndState に送信されます。

注記

ResultPath フィールドを指定しない場合、入力全体を選択して上書きする $ がデフォルトで設定されます。

状態に Retry および Catch フィールドの両方がある場合、Step Functions は最初に該当する retriers を使用し、その後、再試行ポリシーがエラーを解決できなかった場合、一致する catcher を適用します。

Retry の使用例と Catch の使用例

次の例で定義されたステートマシンには、2 つの Lambda 関数があるとします。1 つは常に失敗し、1 つはステートマシンで定義されたタイムアウトが発生するのに十分な時間待機します。

これは、常に失敗してメッセージ error を返す Lambda 関数の定義です。以下のステートマシンの例では、この Lambda 関数の名前は FailFunction です。

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

これは、10 秒間スリープする Lambda 関数の定義です。以下のステートマシンの例では、この Lambda 関数の名前は sleep10 です。

注記

Lambda コンソールでこの Lambda 関数を作成するときは、[Advanced settings] セクションの [Timeout] 値を 3 秒 (デフォルト) から 11 秒に変更してください。

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

Retry を使用して失敗を処理する

このステートマシンは Retry フィールドを使用して、失敗してエラー名 HandledError を出力する関数を再試行します。この関数は 2 回再試行されます。再試行間にはエクスポネンシャルパックオフが使用されます。

{ "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 } } }

このバリエーションでは、Lambda 関数が出力するすべてのエラーに一致する事前定義されたエラーコード States.TaskFailed を使用します。

{ "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 } } }

注記

ベストプラクティスとしては、Lambda 関数をリファレンスするタスクが Lambda サービス例外を処理する必要があります。詳細については、「Lambda サービス例外の処理」を参照してください。

Catch を使用して失敗を処理する

この例では、Catch フィールドを使用します。Lambda 関数がエラーを出力すると、そのエラーがキャッチされ、ステートマシンは 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 } } }

このバリエーションでは、Lambda 関数が出力するすべてのエラーに一致する事前定義されたエラーコード States.TaskFailed を使用します。

{ "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 } } }

Retry を使用してタイムアウトを処理する

このステートマシンは Retry フィールドを使用して、タイムアウトした関数を再試行します。この関数は 2 回再試行されます。再試行間にはエクスポネンシャルパックオフが使用されます。

{ "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 } } }

Catch を使用してタイムアウトを処理する

この例では、Catch フィールドを使用します。タイムアウトが発生すると、ステートマシンは 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 } } }

注記

状態入力とエラーを保持するには、ResultPath を使用します。「ResultPath を使用して、エラーと入力の両方を Catch に含める」を参照してください。