

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 在 Step Functions 中檢查狀態機器執行
<a name="debug-sm-exec-using-ui"></a>

在本教學課程中，您將了解如何檢查執行*詳細資訊*頁面上顯示的執行資訊，並檢視執行失敗的原因。然後，您將了解如何存取`Map`狀態執行的不同反覆運算。最後，您將了解如何在**資料表檢視**上設定資料欄，並套用適當的篩選條件來僅檢視您感興趣的資訊。

在本教學課程中，您會建立標準類型狀態機器，取得一組水果的價格。為此，狀態機器會使用三個 AWS Lambda 函數，傳回四個水果的隨機清單、每個水果的價格，以及水果的平均成本。如果果實的價格小於或等於閾值，Lambda 函數旨在擲回錯誤。

**注意**  
雖然下列程序包含如何檢查標準工作流程執行詳細資訊的指示，您也可以檢查快速工作流程執行的詳細資訊。如需標準和快速工作流程類型執行詳細資訊間差異的資訊，請參閱 [標準和快速主控台體驗差異](concepts-view-execution-details.md#console-exp-differences)。

## 步驟 1：建立和測試所需的 Lambda 函數
<a name="step-create-all-lambda-functions"></a>

1. 開啟 [Lambda 主控台](https://console.aws.amazon.com/lambda/home)，然後執行 [步驟 1：建立 Lambda 函式](tutorial-creating-lambda-state-machine.md#create-lambda-function)區段中的步驟 1 到 4。請務必將 Lambda 函數命名為 **GetListOfFruits**。

1. 建立 Lambda 函數後，複製頁面右上角顯示的函數 Amazon Resource Name (ARN)。若要複製 ARN，請按一下複製圖示以複製 Lambda 函數的 Amazon Resource Name。以下是範例 ARN，其中 *`function-name`*是 Lambda 函數的名稱 （在此案例中為 `GetListOfFruits`)：

   ```
   arn:aws:lambda:region:123456789012:function:function-name
   ```

1. 將 Lambda 函數的下列程式碼複製到 **GetListOfFruits** 頁面的**程式碼來源**區域。

   ```
   function getRandomSubarray(arr, size) {
       var shuffled = arr.slice(0), i = arr.length, temp, index;
       while (i--) {
           index = Math.floor((i + 1) * Math.random());
           temp = shuffled[index];
           shuffled[index] = shuffled[i];
           shuffled[i] = temp;
       }
       return shuffled.slice(0, size);
   }
   
   exports.handler = async function(event, context) {
       
       const fruits = ['Abiu','Açaí','Acerola','Ackee','African cucumber','Apple','Apricot','Avocado','Banana','Bilberry','Blackberry','Blackcurrant','Jostaberry'];
   
       
        const errorChance = 45;
       
       const waitTime = Math.floor( 100 * Math.random() );
   
       await new Promise( r => setTimeout(() => r(), waitTime));
   
       const num = Math.floor( 100 * Math.random() );
       // const num = 51;
        if (num <= errorChance) {
            throw(new Error('Error'));
        }
   
       return getRandomSubarray(fruits, 4);
   };
   ```

1. 選擇**部署**，然後選擇**測試**，以部署變更並查看 Lambda 函數的輸出。

1. **CalculateAverage** 使用下列步驟分別建立兩個名為 **GetFruitPrice**和 的其他 Lambda 函數：

   1. 將下列程式碼複製到 **GetFruitPrice** Lambda 函數的**程式碼來源**區域：

      ```
      exports.handler = async function(event, context) {
          
          const errorChance = 0;
          const waitTime = Math.floor( 100 * Math.random() );
      
          await new Promise( r => setTimeout(() => r(), waitTime));
      
          const num = Math.floor( 100 * Math.random() );
          if (num <= errorChance) {
              throw(new Error('Error'));
          }
      
          return Math.floor(Math.random()*100)/10;
      };
      ```

   1. 將下列程式碼複製到 **CalculateAverage** Lambda 函數的**程式碼來源**區域：

      ```
      function getRandomSubarray(arr, size) {
          var shuffled = arr.slice(0), i = arr.length, temp, index;
          while (i--) {
              index = Math.floor((i + 1) * Math.random());
              temp = shuffled[index];
              shuffled[index] = shuffled[i];
              shuffled[i] = temp;
          }
          return shuffled.slice(0, size);
      }
      
      const average = arr => arr.reduce( ( p, c ) => p + c, 0 ) / arr.length;
          
      exports.handler = async function(event, context) {
              const errors = [
              "Error getting data from DynamoDB",
              "Error connecting to DynamoDB",
              "Network error",
              "MemoryError - Low memory"
              ]
              
          const errorChance = 0;
          
          const waitTime = Math.floor( 100 * Math.random() );
      
          await new Promise( r => setTimeout(() => r(), waitTime));
      
          const num = Math.floor( 100 * Math.random() );
          if (num <= errorChance) {
              throw(new Error(getRandomSubarray(errors, 1)[0]));
          }
      
          return average(event);
      };
      ```

   1. 請務必複製這兩個 Lambda 函數ARNs，然後**部署**和**測試**它們。

## 步驟 2：建立和執行狀態機器
<a name="step-create-exec-sm"></a>

使用 [Step Functions 主控台](https://console.aws.amazon.com/states/home?region=us-east-1#/)建立狀態機器，以叫用[您在步驟 1 中建立的 Lambda 函數](#step-create-all-lambda-functions)。在此狀態機器中，會定義三個`Map`狀態。這些`Map`狀態都包含一個`Task`狀態，可叫用其中一個 Lambda 函數。此外，每個`Task`狀態都會定義 `Retry` 欄位，並為每個狀態定義多次重試嘗試。如果`Task`狀態遇到執行時間錯誤，則會再次執行，直到該 定義的重試嘗試次數為止`Task`。

1. 開啟 [Step Functions 主控台](https://console.aws.amazon.com/states/home)，然後選擇**以程式碼撰寫工作流程**。
**重要**  
確保您的狀態機器與您先前建立的 Lambda 函數位於相同的 AWS 帳戶和區域。

1. 對於**類型**，保留**標準**的預設選擇。

1. 複製下列 Amazon States Language 定義，並將其貼到**定義**下。請務必將顯示的 ARNs 取代為您先前建立的 Lambda 函數的 ARN。

   ```
   {
       "StartAt": "LoopOverStores",
       "States": {
           "LoopOverStores": {
               "Type": "Map",
               "Iterator": {
                   "StartAt": "GetListOfFruits",
                   "States": {
                       "GetListOfFruits": {
                           "Type": "Task",
                           "Resource": "arn:aws:states:::lambda:invoke",
                           "OutputPath": "$.Payload",
                           "Parameters": {
                               "FunctionName": "arn:aws:lambda:region:123456789012:function:GetListofFruits:$LATEST",
                               "Payload": {
                                   "storeName.$": "$"
                               }
                           },
                           "Retry": [
                               {
                                   "ErrorEquals": [
                                       "States.ALL"
                                   ],
                                   "IntervalSeconds": 2,
                                   "MaxAttempts": 1,
                                   "BackoffRate": 1.3
                               }
                           ],
                           "Next": "LoopOverFruits"
                       },
                       "LoopOverFruits": {
                           "Type": "Map",
                           "Iterator": {
                               "StartAt": "GetFruitPrice",
                               "States": {
                                   "GetFruitPrice": {
                                       "Type": "Task",
                                       "Resource": "arn:aws:states:::lambda:invoke",
                                       "OutputPath": "$.Payload",
                                       "Parameters": {
                                           "FunctionName": "arn:aws:lambda:region:123456789012:function:GetFruitPrice:$LATEST",
                                           "Payload": {
                                               "fruitName.$": "$"
                                           }
                                       },
                                       "Retry": [
                                           {
                                               "ErrorEquals": [
                                                   "States.ALL"
                                               ],
                                               "IntervalSeconds": 2,
                                               "MaxAttempts": 3,
                                               "BackoffRate": 1.3
                                           }
                                       ],
                                       "End": true
                                   }
                               }
                           },
                           "ItemsPath": "$",
                           "End": true
                       }
                   }
               },
               "ItemsPath": "$.stores",
               "Next": "LoopOverStoreFruitsPrice",
               "ResultPath": "$.storesFruitsPrice"
           },
           "LoopOverStoreFruitsPrice": {
               "Type": "Map",
               "End": true,
               "Iterator": {
                   "StartAt": "CalculateAverage",
                   "States": {
                       "CalculateAverage": {
                           "Type": "Task",
                           "Resource": "arn:aws:states:::lambda:invoke",
                           "OutputPath": "$.Payload",
                           "Parameters": {
                               "FunctionName": "arn:aws:lambda:region:123456789012:function:Calculate-average:$LATEST",
                               "Payload.$": "$"
                           },
                           "Retry": [
                               {
                                   "ErrorEquals": [
                                       "States.ALL"
                                   ],
                                   "IntervalSeconds": 2,
                                   "MaxAttempts": 2,
                                   "BackoffRate": 1.3
                               }
                           ],
                           "End": true
                       }
                   }
               },
               "ItemsPath": "$.storesFruitsPrice",
               "ResultPath": "$.storesPriceAverage",
               "MaxConcurrency": 1
           }
       }
   }
   ```

1. 輸入狀態機器的名稱。保留此頁面中其他選項的預設選擇，然後選擇**建立狀態機器**。

1. 開啟標題為 狀態機器名稱的頁面。在 [步驟 4：執行狀態機器](tutorial-creating-lambda-state-machine.md#start-lambda-function)區段中執行步驟 1 到 4，但使用下列資料做為執行輸入：

   ```
   {
       "stores": [
         "Store A",
         "Store B",
         "Store C",
         "Store D"
       ]
   }
   ```

## 步驟 3：檢視狀態機器執行詳細資訊
<a name="view-sm-exec-details"></a>

在標題為執行 ID 的頁面上，您可以檢閱執行的結果，並偵錯任何錯誤。

1. （選用） 從*執行詳細資訊*頁面上顯示的索引標籤中選擇，以查看每個索引標籤中存在的資訊。例如，若要檢視狀態機器輸入及其執行輸出，請在**執行摘要區段中選擇執行輸入和輸出**。 *[執行摘要](concepts-view-execution-details.md#exec-details-intf-exec-summ)*

1. 如果您的狀態機器執行失敗，請在錯誤訊息上選擇**原因**或**顯示步驟詳細資訊**。有關錯誤的詳細資訊會顯示在*[步驟詳細資訊](concepts-view-execution-details.md#exec-details-intf-step-details)*區段中。請注意，導致錯誤的步驟，也就是名為 **GetListofFruits** `Task`的狀態，會在**圖形檢視**和**資料表檢視**中反白顯示。
**注意**  
由於 **GetListofFruits** 步驟是在 `Map` 狀態內定義，且步驟無法成功執行，因此`Map`狀態步驟**的狀態**會顯示為 **失敗**。

## 步驟 4：探索不同的*檢視模式*
<a name="sm-exec-details-exp-view-modes"></a>

您可以選擇偏好的模式來檢視狀態機器工作流程或執行事件歷史記錄。您可以在這些*檢視模式中*執行的一些任務如下：

### **圖形檢視** – 在不同的`Map`狀態反覆運算之間切換
<a name="graph-view-see-map-state-iterations"></a>

如果您的**映射**狀態有五個反覆運算，而且您想要檢視第三個和第四個反覆運算的執行詳細資訊，請執行下列動作：

1. 選擇您要檢視反覆運算資料`Map`的狀態。

1. 從**映射反覆運算檢視器**中，選擇您要檢視的反覆運算。反覆運算會從零開始計算。若要從五個反覆運算中選擇第三個反覆運算，請從**映射**狀態名稱旁的下拉式清單中選擇 **\$12**。
**注意**  
如果您的狀態機器包含巢狀`Map`狀態，Step Functions 會將父系和子系`Map`狀態反覆運算顯示為兩個單獨的下拉式清單，代表巢狀狀態的反覆運算資料。

1. （選用） 如果您的一或多個`Map`狀態反覆運算無法執行或停止為中止狀態，您可以檢視失敗反覆運算的詳細資訊。若要查看這些詳細資訊，請在下拉式清單中選擇**失敗**或**中止**下受影響的反覆運算號碼。

### **資料表檢視** – 在不同的`Map`狀態反覆運算之間切換
<a name="table-view-see-map-state-iterations"></a>

如果您的**映射**狀態有五個反覆運算，而且您想要檢視反覆運算編號 3 和 4 的執行詳細資訊，請執行下列動作：

1. 選擇您要檢視不同反覆運算資料`Map`的狀態。

1. 在`Map`狀態反覆運算的樹狀檢視畫面中，選擇名稱為 **\$12** 的反覆運算列，表示反覆運算 \$13。同樣地，請為第四個反覆運算選擇名為 **\$13** 的資料列。

### **資料表檢視** – 設定要顯示的資料欄
<a name="table-view-cfg-display-cols"></a>

選擇設定圖示。然後，在**偏好設定**對話方塊中，選擇您要在**選取可見資料欄下顯示的資料欄**。

根據預設，此模式會顯示**名稱**、**類型**、**狀態**、**資源**和**啟動後**資料欄。

### **資料表檢視** – 篩選結果
<a name="table-view-filter-results"></a>

根據**狀態**或日期和時間範圍等屬性套用一或多個篩選條件，以限制顯示的資訊量。例如，若要檢視執行失敗的步驟，請套用下列篩選條件：

1. 選擇**依屬性篩選或依關鍵字搜尋**，然後在**屬性**下選擇**狀態**。

1. 在**運算子**下，選擇**狀態 =**。

1. 選擇**狀態 = 失敗**。

1. （選用） 選擇**清除篩選條件**以移除套用的篩選條件。

### **事件檢視** – 篩選結果
<a name="event-view-filter-results"></a>

根據**類型**或日期和時間範圍等屬性套用一或多個篩選條件，以限制顯示的資訊量。例如，若要檢視執行失敗`Task`的狀態步驟，請套用下列篩選條件：

1. 選擇**依屬性篩選或依關鍵字搜尋**，然後選擇**屬性**下的**類型**。

1. 在**運算子**下，選擇**類型 =**。

1. 選擇**類型 = TaskFailed**。

1. （選用） 選擇**清除篩選條件**以移除套用的篩選條件。

### **事件檢視** – 檢查 **TaskFailed** 事件詳細資訊
<a name="event-view-inspect-failed-task-details"></a>

選擇 **TaskFailed** 事件 ID 旁的箭頭圖示，以檢查其詳細資訊，包括顯示在下拉式清單中的輸入、輸出和資源調用。