本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。
處理 Step Functions 工作流程中的錯
除了Pass
和狀態之外的所有Wait
狀態都可能會遇到執行階段錯誤。錯誤可能由於各種原因而發生,例如:
-
狀態機器定義問題 (例如,
Choice
狀態中沒有相符的規則) -
工作失敗 (例如, AWS Lambda 函數)
-
暫時性問題 (例如,網路分割區事件)
默認情況下,當狀態報告錯誤時, AWS Step Functions 導致執行完全失敗。
提示
若要將包含錯誤處理的工作流程範例部署到 AWS 帳戶,請參閱「錯誤處理
錯誤名稱
Step Functions 使用區分大小寫的字串 (稱為錯誤名稱) 識別 Amazon 州語言中的錯誤。Amazon States 語言會定義一組內建字串,這些字串命名為已知錯誤,全部都以前置States.
詞開頭。
-
States.ALL
-
符合任何已知錯誤名稱的萬用字元。
注意
此錯誤類型無法 catch
States.DataLimitExceeded
終端錯誤類型和運行時錯誤類型。如需這些錯誤類型的詳細資訊,請參閱States.DataLimitExceeded和States.Runtime。 -
States.DataLimitExceeded
-
報告由於以下情況:
-
當連接器的輸出大於有效負載大小配額時。
-
當狀態的輸出大於有效負載大小配額時。
-
Parameters
處理之後,狀態的輸入大於有效負載大小配額時。
如需配額的詳細資訊,請參閱Step Functions 服務配額。
注意
這是錯誤類型無法捕獲的終端
States.ALL
錯誤。 -
States.ExceedToleratedFailureThreshold
Map
狀態失敗,因為失敗的項目數超過狀態機器定義中指定的臨界值。如需詳細資訊,請參閱在 Step Functions 中設定分散式對應狀態的失敗臨界值。-
States.HeartbeatTimeout
-
狀
Task
態無法傳送活動訊號超過該HeartbeatSeconds
值的時間。注意
此錯誤僅在
Catch
和Retry
欄位中可用。 -
States.Http.Socket
-
當HTTP工作時間大約在 60 秒後,就會發生這個錯誤。請參閱 與HTTP工作相關的配額。
-
States.IntrinsicFailure
-
嘗試在有效負載範本中叫用內建函式失敗。
States.ItemReaderFailed
狀
Map
態失敗,因為無法從ItemReader
欄位中指定的項目來源讀取。如需詳細資訊,請參閱ItemReader (地圖)
。-
States.NoChoiceMatched
-
Choice
狀態無法將輸入與「選擇規則」中定義的條件相符,且未指定「預設」轉移。 -
States.ParameterPathFailure
-
嘗試取代狀態欄位中名稱以
.$
使用路徑結尾的Parameters
欄位失敗。 -
States.Permissions
-
Task
狀態失敗,因為它沒有足夠的權限來運行指定的代碼。 -
States.ResultPathMatchFailure
-
Step Functions 無法將狀態的
ResultPath
字段應用於輸入接收到的狀態。 States.ResultWriterFailed
狀
Map
態失敗,因為無法將結果寫入ResultWriter
欄位中指定的目的地。如需詳細資訊,請參閱ResultWriter (地圖)
。States.Runtime
-
由於某些無法處理的例外狀況,執行失敗。這些通常是由運行時錯誤引起的,例如嘗試應用
InputPath
或OutputPath
在空有JSON效負載上。States.Runtime
錯誤無法重新擷取,而且永遠會導致執行失敗。重試或 catchStates.ALL
獲不會 catch 獲States.Runtime
錯誤。 -
States.TaskFailed
-
在執行期間失敗的
Task
狀態。在重試或 catch 中使用時,States.TaskFailed
充當通配符,匹配除了任何已知的錯誤名稱States.Timeout
。 -
States.Timeout
-
執行時間超過
TimeoutSeconds
值,或無法傳送活動訊號的時間超過HeartbeatSeconds
值的Task
狀態。此外,如果狀態機器的執行時間超過指定
TimeoutSeconds
值,則執行會失敗並顯示States.Timeout
錯誤。
狀態可以回報具有其他名稱的錯誤。但是,這些錯誤名稱不能以States.
前綴開頭。
作為最佳實踐,確保生產代碼可以處理 AWS Lambda 服務例外(Lambda.ServiceException
和Lambda.SdkClientException
)。如需詳細資訊,請參閱處理暫態 Lambda 服務例外。
注意
Lambda 中未處理的錯誤會報告為錯誤輸出Lambda.Unknown
中。這些包括 out-of-memory 錯誤和功能超時。您可以在Lambda.Unknown
States.ALL
、或上進行比對States.TaskFailed
來處理這些錯誤。當 Lambda 達到調用的最大數量時,錯誤為。Lambda.TooManyRequestsException
如需 Lambda Handled
和Unhandled
錯誤的詳細資訊,請參閱FunctionError
中的 AWS Lambda 開發人員指南。
發生錯誤後重試
Task
、Parallel
、和Map
狀態可以有一個名為的欄位Retry
,其值必須是稱為擷取器的物件陣列。個別的 Retrier 代表特定的重試次數,通常為較長的時間間隔。
當其中一個狀態報告錯誤且有Retry
欄位時,Step Functions 會依陣列中列出的順序掃描擷取器。當錯誤名稱出現在檢索器欄位的值中時,狀態機會按照ErrorEquals
欄位中的定義進行重試嘗試。Retry
如果您的 redriven 執行會重新執行工作流程狀態平行工作流狀態、或 Inline Map 狀態 (您已針對其定義重試),這些狀態的重試嘗試次數會重設為 0,以允許嘗試次數上限 redrive。 對於一個 redriven 執行時,您可以使用控制台跟踪這些狀態的個別重試嘗試。如需詳細資訊,請參閱 使用 重新啟動狀態機器執行 redrive 在步驟函數中 中的 的重試行為 redriven 執行。
Retrier 包含下列欄位:
注意
重試被視為狀態轉換。有關狀態轉換如何影響計費的詳細資訊,請參閱 Step Functions 定價
-
ErrorEquals
(必要) -
符合錯誤名稱的非空白字串陣列。當狀態報告錯誤時,「Step Functions」會透過擷取器進行掃描。當錯誤名稱出現於此陣列時,它會實作此 Retrier 中所述的重試政策。
-
IntervalSeconds
(選用) -
正整數;代表第一次嘗試重試前的秒數 (
1
預設情況下)。IntervalSeconds
其最大值為 99999999。 -
MaxAttempts
(選用) -
正整數,其代表重試次數上限 (預設值
3
)。如果出現錯誤的次數超過指定次數,則重試會停止且一般錯誤處理會繼續執行。值0
指定永遠不會重試錯誤。MaxAttempts
其最大值為 99999999。 -
BackoffRate
(選用) -
每次重試嘗試後,表示重試間隔的乘數
IntervalSeconds
會增加。依預設,BackoffRate
值會增加2.0
。例如,假設你
IntervalSeconds
是 3,MaxAttempts
是 3,BackoffRate
是 2。第一次重試嘗試會在錯誤發生後三秒鐘進行。第二次重試會在第一次嘗試重試後六秒進行。第三次重試會在第二次重試嘗試後 12 秒進行。 -
MaxDelaySeconds
(選用) -
正整數;設定重試間隔可以增加的最大值 (以秒為單位)。此欄位對於欄位搭配使用很有幫助。
BackoffRate
您在此欄位中指定的值會限制套用至每次連續重試嘗試的輪詢率乘數所產生的指數等待時間。您必須指定一個大於 0 且小於 31622401 的值。MaxDelaySeconds
如果未指定此值,Step Functions 不會限制重試嘗試之間的等待時間。
-
JitterStrategy
(選用) -
字串,決定是否要在連續重試嘗試之間的等待時間中包含抖動。抖動會在隨機延遲間隔內分散這些嘗試,以減少同時重試的次數。該字符串接受
FULL
或NONE
作為其值。預設值為NONE
。例如,假設您已設定
MaxAttempts
IntervalSeconds
為 3、為 2 和BackoffRate
2。第一次重試嘗試會在錯誤發生後兩秒鐘進行。第二次重試會在第一次重試嘗試後四秒進行,第三次重試會在第二次重試嘗試後 8 秒進行。如果設定JitterStrategy
為FULL
,則第一個重試間隔會在 0 到 2 秒之間隨機排列,第二個重試間隔會在 0 到 4 秒之間隨機排列,第三個重試間隔會在 0 到 8 秒之間隨機排列。
重試欄位範例
本節包含下列Retry
欄位範例。
提示
若要將錯誤處理工作流程的範例部署至 AWS 帳戶,請參閱 「錯誤處理
範例 1 — 重試 BackoffRate
下列的範例Retry
會在等待三秒鐘後進行兩次重試,而第一次重試會進行。根據BackoffRate
您指定的,「Step Functions 數」會增加每次重試之間的間隔,直到達到重試嘗試次數上限為止。在下列範例中,第二次重試嘗試會在第一次重試後等待三秒鐘後開始。
"Retry": [ {
"ErrorEquals": [ "States.Timeout" ],
"IntervalSeconds": 3,
"MaxAttempts": 2,
"BackoffRate": 1
} ]
範例 2 — 重試 MaxDelaySeconds
下列範例會進行三次重試,並限制 5 秒後產生的BackoffRate
等待時間。第一次重試會在等待三秒鐘後進行。第二次和第三次重試嘗試會在前一次重試嘗試後等待五秒鐘後發生,因為等待時間上限是由設定的最大等待時間限制MaxDelaySeconds
。
"Retry": [ {
"ErrorEquals": [ "States.Timeout" ],
"IntervalSeconds": 3,
"MaxAttempts": 3,
"BackoffRate":2,
"MaxDelaySeconds": 5,
"JitterStrategy": "FULL"
} ]
如果沒有MaxDelaySeconds
,則第二次重試會在第一次重試六秒後進行,第三次重試會在第二次重試後 12 秒進行。
範例 3 — 重試除狀態之外的所有錯誤。逾時
出現在 Retrier 的 ErrorEquals
欄位中的預留名稱 States.ALL
是符合任何錯誤名稱的萬用字元。它必須單獨顯示在 ErrorEquals
陣列中,而且必須顯示在 Retry
陣列的最後一個 Retrier 中。該名稱States.TaskFailed
還具有通配符,並匹配除外的任何錯誤States.Timeout
。
下列Retry
欄位範例會重試除外States.Timeout
的任何錯誤。
"Retry": [ {
"ErrorEquals": [ "States.Timeout" ],
"MaxAttempts": 0
}, {
"ErrorEquals": [ "States.ALL" ]
} ]
範例 4 — 複雜的重試案例
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"
} ]
}
此工作連續失敗四次,輸出以下錯誤名稱:ErrorA
ErrorB
、ErrorC
、和ErrorB
。因此會發生下列情況:
-
前兩個錯誤匹配第一個檢索器,並導致等待一秒和兩秒。
-
第三個錯誤匹配第二個檢索器,並導致等待五秒鐘。
-
第四個錯誤也匹配第一個檢索器。但是,對於該特定錯誤,它已經達到了兩次 retry(
MaxAttempts
)的最大值。因此,該擷取器會失敗,而且執行會透過Catch
欄位將工作流程重新導向至Z
狀態。
后援国家
Task
Map
和Parallel
狀態每個狀態都可以有一個名為的欄位Catch
。此欄位的值必須物件陣列,也稱為 Catcher。
Catcher 包含下列欄位。
-
ErrorEquals
(必要) -
符合錯誤名稱的非空白字串陣列,其指定方式完全與同名的 Retrier 欄位一樣。
-
Next
(必要) -
字串,該字串必須完全符合其中一個狀態機器的狀態名稱。
-
ResultPath
(選用) -
決定捕捉器傳送到
Next
欄位中指定狀態的輸入的路徑。
當狀態報告錯誤且沒有Retry
欄位,或者如果重試無法解決錯誤,Step Functions 會依陣列中列出的順序掃描擷取器。當錯誤名稱顯示於 Catcher 的 ErrorEquals
欄位值時,狀態機器會轉換到 Next
欄位中具名的狀態。
出現在 Catcher 的 ErrorEquals
欄位中的預留名稱 States.ALL
是符合任何錯誤名稱的萬用字元。它必須單獨顯示在 ErrorEquals
陣列中,而且必須顯示在 Catch
陣列的最後一個 Catcher 中。該名稱States.TaskFailed
還具有通配符,並匹配除外的任何錯誤States.Timeout
。
下列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
欄位,會造成兩種可能性:
-
它會取得該狀態執行的結果,並覆寫狀態輸入的全部或部分。
-
它會取得結果,並將結果新增至輸入。在捕手處理錯誤的情況下,狀態的執行結果是錯誤輸出。
因此,對於示例中的第一個捕獲器,捕手將錯誤輸出添加到輸入中,error-info
如果輸入中還沒有具有此名稱的字段,則命名為的字段。然後,捕手將整個輸入發送到RecoveryState
。對於第二個捕獲器,錯誤輸出會覆蓋輸入,捕手僅將錯誤輸出發送到EndState
。
注意
如未指定 ResultPath
欄位,它會預設為 $
,該值會選取並覆寫整個輸入。
當一個狀態同時具有Retry
和Catch
字段時,Step Functions 首先使用任何適當的檢索器。如果重試原則無法解決錯誤,「Step Functions」會套用相符的捕捉器轉換。
原因有效載荷和服務整合
捕手返回一個字符串有效載荷作為輸出。使用 Amazon Athena 之類的服務集成或 AWS CodeBuild,您可能希望將Cause
字符串轉換為JSON。以下具有內在函數的Pass
狀態示例演示了如何將Cause
字符串轉換為。JSON
"Handle escaped JSON with JSONtoString": {
"Type": "Pass",
"Parameters": {
"Cause.$": "States.StringToJson($.Cause)"
},
"Next": "Pass State with Pass Processing"
},
使用「重試」和使用 Catch 的狀態機示例
以下範例中定義的狀態機器假設存在兩個 Lambda 函數:一個永遠失敗,另一個等待足夠長的時間以允許狀態機器中定義的逾時發生。
這是一個 Node.js Lambda 函數的定義,它總是失敗,返回消息error
。在接下來的狀態機範例中,會命名此 Lambda 函數FailFunction
。如需建立 Lambda 函數的相關資訊,請參閱一步驟 1:建立 Lambda 函數節。
exports.handler = (event, context, callback) => {
callback("error");
};
這是一個 Node.js Lambda 函數的定義,睡眠 10 秒。在接下來的狀態機範例中,會命名此 Lambda 函數sleep10
。
注意
在 Lambda 主控台中建立此 Lambda 函數時,請記得將 [進階設定] 區段中的逾時值從 3 秒 (預設值) 變更為 11 秒。
exports.handler = (event, context, callback) => {
setTimeout(function(){
}, 11000);
};
使用「重試」處理失敗
此狀態機器會使用 Retry
欄位來重試失敗且輸出錯誤名稱 HandledError
的函數。它重試此函數兩次,並在重試之間進行指數輪詢。
{
"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
}
}
}
此變體使用預先定義的錯誤代碼States.TaskFailed
,該代碼與 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
}
}
}
注意
最佳實務是,參考 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
}
}
}
此變體使用預先定義的錯誤代碼States.TaskFailed
,該代碼與 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
}
}
}
使用「重試」處理逾時
此狀態機器會根據中指定的逾時值,使用Retry
欄位重試逾時的Task
狀態TimeoutSeconds
。Step Functions 數會在此Task
狀態下重試 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: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。