Azure Logic Apps におけるエラーと例外の処理Handle errors and exceptions in Azure Logic Apps

あらゆる統合アーキテクチャに言えることですが、依存システムに起因するダウンタイムや問題の適切な処理方法には難しい問題が伴うことがあります。The way that any integration architecture appropriately handles downtime or issues caused by dependent systems can pose a challenge. 問題やエラーを円滑に処理する堅牢で回復力の高い統合を構築しやすいよう、Logic Apps には、エラーと例外の処理に関してきわめて優れた機能が用意されています。To help you create robust and resilient integrations that gracefully handle problems and failures, Logic Apps provides a first-class experience for handling errors and exceptions.

再試行ポリシーRetry policies

"再試行ポリシー" は、例外とエラーの最も基本的な処理として、それをサポートしているあらゆるアクションやトリガーで使うことができます。For the most basic exception and error handling, you can use a retry policy in any action or trigger where supported. 最初の要求がタイムアウトしたりエラーが発生したりした場合 (つまり何らかの要求に対する応答として 408、429、5xx のいずれかが返された場合)、アクションまたはトリガーが要求を再試行するかどうか、また、どのように再試行するかを再試行ポリシーで指定します。A retry policy specifies whether and how the action or trigger retries a request when the original request times out or fails, which is any request that results in a 408, 429, or 5xx response. 他の再試行ポリシーが使用されていない場合は、既定のポリシーが使用されます。If no other retry policy is used, the default policy is used.

再試行ポリシーの種類を次に示します。Here are the retry policy types:

TypeType 説明Description
既定値Default このポリシーは、"指数関数的に増加" する間隔で、最大 4 回の再試行を送信します。間隔の増加係数は 7.5 秒で、下限と上限はそれぞれ 5 秒と 45 秒になります。This policy sends up to four retries at exponentially increasing intervals, which scale by 7.5 seconds but are capped between 5 and 45 seconds.
指数間隔Exponential interval このポリシーは、指数関数的に増加する範囲から選択されるランダムな間隔を待ち時間として、次の要求を送信します。This policy waits a random interval selected from an exponentially growing range before sending the next request.
固定間隔Fixed interval このポリシーは、指定された間隔を待ち時間として、次の要求を送信します。This policy waits the specified interval before sending the next request.
なしNone 要求を再送信しません。Don't resend the request.

再試行ポリシーの制限については、「Logic Apps の制限と構成」をご覧ください。For information about retry policy limits, see Logic Apps limits and configuration.

再試行ポリシーの変更Change retry policy

異なる再試行ポリシーを選択するには、次の手順に従います。To select a different retry policy, follow these steps:

  1. ロジック アプリ デザイナーでロジック アプリを開きます。Open your logic app in Logic App Designer.

  2. アクションまたはトリガーの [設定] を開きます。Open the Settings for an action or trigger.

  3. アクションまたはトリガーが再試行ポリシーをサポートしている場合、 [再試行ポリシー] で目的の種類を選択します。If the action or trigger supports retry policies, under Retry Policy, select the type you want.

または、再試行ポリシーをサポートするアクションまたはトリガーの inputs セクションで、再試行ポリシーを手動で指定することもできます。Or, you can manually specify the retry policy in the inputs section for an action or trigger that supports retry policies. 再試行ポリシーを指定しなかった場合は、既定のポリシーが使用されます。If you don't specify a retry policy, the action uses the default policy.

"<action-name>": {
   "type": "<action-type>", 
   "inputs": {
      "<action-specific-inputs>",
      "retryPolicy": {
         "type": "<retry-policy-type>",
         "interval": "<retry-interval>",
         "count": <retry-attempts>,
         "minimumInterval": "<minimum-interval>",
         "maximumInterval": "<maximun-interval>"
      },
      "<other-action-specific-inputs>"
   },
   "runAfter": {}
}

必須Required

Value TypeType 説明Description
<retry-policy-type><retry-policy-type> stringString 使用する再試行ポリシーの種類: defaultnonefixed、または exponentialThe retry policy type you want to use: default, none, fixed, or exponential
<retry-interval><retry-interval> stringString 再試行間隔。この値には ISO 8601 形式を使用する必要があります。The retry interval where the value must use ISO 8601 format. 既定の最小間隔は PT5S で、最大間隔は PT1D です。The default minimum interval is PT5S and the maximum interval is PT1D. 指数の間隔ポリシーを使用するとき、最小と最大にさまざまな値を指定できます。When you use the exponential interval policy, you can specify different minimum and maximum values.
<retry-attempts><retry-attempts> 整数Integer 再試行の回数。1 - 90 で指定する必要があります。The number of retry attempts, which must be between 1 and 90

省略可能Optional

Value TypeType 説明Description
<minimum-interval><minimum-interval> stringString 指数間隔ポリシーに関して、ランダムに選択される間隔の最小値です (ISO 8601 形式)。For the exponential interval policy, the smallest interval for the randomly selected interval in ISO 8601 format
<maximum-interval><maximum-interval> stringString 指数間隔ポリシーに関して、ランダムに選択される間隔の最大値です (ISO 8601 形式)。For the exponential interval policy, the largest interval for the randomly selected interval in ISO 8601 format

以下、各種のポリシーについて説明します。Here is more information about the different policy types.

DefaultDefault

再試行ポリシーを指定しなかった場合は、既定のポリシーが使用されます。実質的には指数間隔ポリシーであり、最大 4 回の再試行が送信される間隔は、7.5 秒を増加係数として指数関数的に増やされます。If you don't specify a retry policy, the action uses the default policy, which is actually an exponential interval policy that sends up to four retries at exponentially increasing intervals that are scaled by 7.5 seconds. 間隔の範囲は 5 秒から 45 秒です。The interval is capped between 5 and 45 seconds.

実際のアクションやトリガーで既定のポリシーを明示的に定義することはありませんが、HTTP アクションを例に、既定のポリシーの動作を以下に示します。Though not explicitly defined in your action or trigger, here is how the default policy behaves in an example HTTP action:

"HTTP": {
   "type": "Http",
   "inputs": {
      "method": "GET",
      "uri": "http://myAPIendpoint/api/action",
      "retryPolicy" : {
         "type": "exponential",
         "interval": "PT7S",
         "count": 4,
         "minimumInterval": "PT5S",
         "maximumInterval": "PT1H"
      }
   },
   "runAfter": {}
}

なしNone

失敗した要求を再試行しないようアクションまたはトリガーに指定するには、<retry-policy-type> を none に設定します。To specify that the action or trigger doesn't retry failed requests, set the <retry-policy-type> to none.

固定間隔Fixed interval

指定した間隔の経過後に次の要求を送信するようアクションまたはトリガーに指定するには、<retry-policy-type> を fixed に設定します。To specify that the action or trigger waits the specified interval before sending the next request, set the <retry-policy-type> to fixed.

Example

この再試行ポリシーは、最新のニュースを取得する要求が失敗した後、2 回の再試行を行います。それぞれの再試行間には 30 秒の延期期間が設けられます。This retry policy attempts to get the latest news two more times after the first failed request with a 30-second delay between each attempt:

"Get_latest_news": {
   "type": "Http",
   "inputs": {
      "method": "GET",
      "uri": "https://mynews.example.com/latest",
      "retryPolicy": {
         "type": "fixed",
         "interval": "PT30S",
         "count": 2
      }
   }
}

指数関数的な間隔Exponential interval

ランダムな間隔の経過後に次の要求を送信するようアクションまたはトリガーに指定するには、<retry-policy-type> を exponential に設定します。To specify that the action or trigger waits a random interval before sending the next request, set the <retry-policy-type> to exponential. ランダムな間隔は、指数関数的に増加する範囲から選択されます。The random interval is selected from an exponentially growing range. 最小間隔と最大間隔の既定値は、それぞれ独自の間隔を指定することにより、必要に応じて上書きすることができます。Optionally, you can also override the default minimum and maximum intervals by specifying your own minimum and maximum intervals.

ランダム変数の範囲Random variable ranges

次の表を見ると、最大再試行回数に到達するまで、指定された範囲内の一様なランダム変数が再試行ごとに生成されるようすがわかります。This table shows how Logic Apps generates a uniform random variable in the specified range for each retry up to and including the number of retries:

再試行回数Retry number 最小間隔Minimum interval 最大間隔Maximum interval
11 max(0, <minimum-interval>)max(0, <minimum-interval>) min(interval, <maximum-interval>)min(interval, <maximum-interval>)
22 max(interval, <minimum-interval>)max(interval, <minimum-interval>) min(2 * interval, <maximum-interval>)min(2 * interval, <maximum-interval>)
33 max(2 * interval, <minimum-interval>)max(2 * interval, <minimum-interval>) min(4 * interval, <maximum-interval>)min(4 * interval, <maximum-interval>)
44 max(4 * interval, <minimum-interval>)max(4 * interval, <minimum-interval>) min(8 * interval, <maximum-interval>)min(8 * interval, <maximum-interval>)
........ ........ ........

runAfter プロパティを使用してエラーをキャッチして処理するCatch and handle failures with the RunAfter property

ロジック アプリの各アクションは、そのアクションが開始する前に終了する必要があるアクションを宣言します。これは、ワークフローのステップの順序を指定する方法と同じです。Each logic app action declares the actions that must finish before that action starts, similar to how you specify the order of steps in your workflow. アクションの定義において、runAfter プロパティはこの順序を定義します。また、このプロパティは、特定のアクションを実行するうえでの前提条件となるアクションとその状態を記述するオブジェクトです。In an action definition, the runAfter property defines this ordering and is an object that describes which actions and action statuses execute the action.

既定では、ロジック アプリ デザイナーで追加されたすべてのアクションは、先行する手順の結果が Succeeded であれば、その手順の次に実行されるように設定されます。By default, all actions that you add in the Logic App Designer are set to run after the previous step when the previous step's result is Succeeded. ただし、runAfter の値をカスタマイズして、先行するアクションの結果が FailedSkipped (または組み合わせ) の場合にもアクションが起動するようにできます。However, you can customize the runAfter value so that actions fire when the previous actions result as Failed, Skipped, or some combination of these values. たとえば、特定の Insert_Row アクションが失敗した後で、特定の Service Bus トピックに項目を追加するには、次の例の runAfter 定義を使用できます。For example, to add an item to a specific Service Bus topic after a specific Insert_Row action fails, you could use this example runAfter definition:

"Send_message": {
    "inputs": {
        "body": {
            "ContentData": "@{encodeBase64(body('Insert_Row'))}",
            "ContentType": "{ \"content-type\" : \"application/json\" }"
        },
        "host": {
            "api": {
                "runtimeUrl": "https://logic-apis-westus.azure-apim.net/apim/servicebus"
            },
            "connection": {
                "name": "@parameters('$connections')['servicebus']['connectionId']"
            }
        },
        "method": "post",
        "path": "/@{encodeURIComponent('failures')}/messages"
    },
    "runAfter": {
        "Insert_Row": [
            "Failed"
        ]
    }
}

この runAfter プロパティは、Insert_Row アクションの状態が Failed のときに実行するように設定されています。The runAfter property is set to run when the Insert_Row action status is Failed. アクションの状態が SucceededFailed、または Skipped の場合にアクションを実行するには、次の構文を使用します。To run the action if the action status is Succeeded, Failed, or Skipped, use this syntax:

"runAfter": {
        "Insert_Row": [
            "Failed", "Succeeded", "Skipped"
        ]
    }

ヒント

先行するアクションが失敗した後で実行され、正常に完了したアクションは Succeeded とマークされます。Actions that run and finish successfully after a preceding action has failed, are marked as Succeeded. この動作は、ワークフロー内で発生したすべてのエラーが正常にキャッチされた場合、その実行そのものは Succeeded としてマークされることを意味します。This behavior means that if you successfully catch all failures in a workflow, the run itself is marked as Succeeded.

スコープとその結果を使用してアクションを評価するEvaluate actions with scopes and their results

runAfter プロパティを使用して個々のアクションの後で手順を実行するように、アクションをスコープにまとめることができます。Similar to running steps after individual actions with the runAfter property, you can group actions together inside a scope. アクションを論理的にグループ化し、スコープの集合的な状態を調査し、その状態に基づいてアクションを実行する場合は、スコープを使用できます。You can use scopes when you want to logically group actions together, assess the scope's aggregate status, and perform actions based on that status. そのスコープ内のすべてのアクションの実行が完了すると、スコープが独自の状態を取得します。After all the actions in a scope finish running, the scope itself gets its own status.

スコープの状態を調べるには、ロジック アプリの実行状態を調べるのと同じ基準 (SucceededFailed など) を使用できます。To check a scope's status, you can use the same criteria that you use to check a logic app's run status, such as Succeeded, Failed, and so on.

既定では、スコープのすべてのアクションが成功すると、そのスコープの状態は Succeeded とマークされます。By default, when all the scope's actions succeed, the scope's status is marked Succeeded. スコープの最後のアクションが Failed または Aborted になると、スコープの状態は Failed とマークされます。If the final action in a scope results as Failed or Aborted, the scope's status is marked Failed.

Failed スコープの例外をキャッチして、そのエラーを処理するアクションを実行するには、その Failed スコープの runAfter プロパティを使用できます。To catch exceptions in a Failed scope and run actions that handle those errors, you can use the runAfter property for that Failed scope. このように、スコープ内の "いずれかの" アクションが失敗したときに、そのスコープに対して runAfter プロパティを使用している場合、エラーをキャッチする 1 つのアクションを作成できます。That way, if any actions in the scope fail, and you use the runAfter property for that scope, you can create a single action to catch failures.

スコープの制限については、制限と構成に関するページをご覧ください。For limits on scopes, see Limits and config.

エラーのコンテキストと結果を取得するGet context and results for failures

スコープ単位でエラーをキャッチできるのは便利ですが、失敗したアクションや返されたエラーまたは状態コードを正確に把握するためには、スコープの結果だけでなくコンテキストが必要となります。Although catching failures from a scope is useful, you might also want context to help you understand exactly which actions failed plus any errors or status codes that were returned.

result() 関数を使用すると、スコープ内のすべてのアクションの結果に関するコンテキストが得られます。The result() function provides context about the results from all the actions in a scope. result() 関数は、単一のパラメーター (スコープの名前) を受け取り、そのスコープ内のアクションの結果をすべて含む配列を返します。The result() function accepts a single parameter, which is the scope's name, and returns an array that contains all the action results from within that scope. これらのアクションのオブジェクトには、@actions() オブジェクトと同じ属性 (アクションの開始時刻、終了時刻、状態、入力、相関 ID、出力など) が含まれます。These action objects include the same attributes as the @actions() object, such as the action's start time, end time, status, inputs, correlation IDs, and outputs. @result() 式と runAfter プロパティを組み合わせるだけで、スコープ内で失敗したすべてのアクションのコンテキストを受け取ることができます。To send context for any actions that failed within a scope, you can easily pair a @result() expression with the runAfter property.

スコープ内の Failed となったアクションごとにアクションを実行し、失敗したアクションに到達するまで結果の配列をフィルター処理するには、@result() 式を [配列のフィルター処理] アクションと For each ループと組み合わせて使用します。To run an action for each action in a scope that has a Failed result, and to filter the array of results down to the failed actions, you can pair a @result() expression with a Filter Array action and a For each loop. 抽出した結果の配列を For each ループに渡すことで、それぞれのエラーに対してアクションを実行することができます。You can take the filtered result array and perform an action for each failure using the For each loop.

次の例では、"My_Scope" というスコープ内で失敗したすべてのアクションの応答本文を含む HTTP POST 要求が送信されます (詳細については例の後に記載)。Here's an example, followed by a detailed explanation, that sends an HTTP POST request with the response body for any actions that failed within the scope "My_Scope":

"Filter_array": {
   "type": "Query",
   "inputs": {
      "from": "@result('My_Scope')",
      "where": "@equals(item()['status'], 'Failed')"
   },
   "runAfter": {
      "My_Scope": [
         "Failed"
      ]
    }
},
"For_each": {
   "type": "foreach",
   "actions": {
      "Log_exception": {
         "type": "Http",
         "inputs": {
            "method": "POST",
            "body": "@item()['outputs']['body']",
            "headers": {
               "x-failed-action-name": "@item()['name']",
               "x-failed-tracking-id": "@item()['clientTrackingId']"
            },
            "uri": "http://requestb.in/"
         },
         "runAfter": {}
      }
   },
   "foreach": "@body('Filter_array')",
   "runAfter": {
      "Filter_array": [
         "Succeeded"
      ]
   }
}

上の例における実際の動作についての詳細は以下のとおりです。Here's a detailed walkthrough that describes what happens in this example:

  1. "My_Scope" 内のすべてのアクションの結果を取得するために、 [配列のフィルター処理] アクションには、@result('My_Scope') というフィルター式が使用されますTo get the result from all actions inside "My_Scope", the Filter Array action uses this filter expression: @result('My_Scope')

  2. [配列のフィルター処理] の条件は、状態が Failed と等しいすべての @result() 項目です。The condition for Filter Array is any @result() item that has a status equal to Failed. この条件により、"My_Scope" のすべてのアクションの結果を含む配列がフィルター処理され、失敗したアクションの結果のみを抽出した配列が得られます。This condition filters the array that has all the action results from "My_Scope" down to an array with only the failed action results.

  3. "フィルター後の配列" の出力に対して For each ループ アクションを実行します。Perform a For each loop action on the filtered array outputs. このステップでは、フィルター処理済みの失敗したアクションの結果ごとに特定のアクションが実行されます。This step performs an action for each failed action result that was previously filtered.

    スコープ内の 1 つのアクションが失敗した場合、For each ループ内のアクションは 1 回だけ実行されます。If a single action in the scope failed, the actions in the For each loop run only once. 失敗したアクションが複数ある場合は、エラーごとに 1 つのアクションが実行されます。Multiple failed actions cause one action per failure.

  4. For each 項目の応答本文すなわち @item()['outputs']['body'] 式で HTTP POST を送信します。Send an HTTP POST on the For each item response body, which is the @item()['outputs']['body'] expression.

    @result() 項目の構造は @actions() と同じであり、同じ方法で解析することができます。The @result() item shape is the same as the @actions() shape and can be parsed the same way.

  5. @item()['name']@item()['clientTrackingId'] という 2 つのカスタム ヘッダーが含まれます。前者は失敗したアクションの名前、後者は失敗した実行のクライアント追跡 ID です。Include two custom headers with the failed action name (@item()['name']) and the failed run client tracking ID (@item()['clientTrackingId']).

参考例として、前述の例で解析した namebodyclientTrackingId の各プロパティを含む 1 つの @result() 項目を次に示します。For reference, here's an example of a single @result() item, showing the name, body, and clientTrackingId properties that are parsed in the previous example. For each アクションの外側では、@result() によってこれらのオブジェクトの配列が返されます。Outside a For each action, @result() returns an array of these objects.

{
   "name": "Example_Action_That_Failed",
   "inputs": {
      "uri": "https://myfailedaction.azurewebsites.net",
      "method": "POST"
   },
   "outputs": {
      "statusCode": 404,
      "headers": {
         "Date": "Thu, 11 Aug 2016 03:18:18 GMT",
         "Server": "Microsoft-IIS/8.0",
         "X-Powered-By": "ASP.NET",
         "Content-Length": "68",
         "Content-Type": "application/json"
      },
      "body": {
         "code": "ResourceNotFound",
         "message": "/docs/folder-name/resource-name does not exist"
      }
   },
   "startTime": "2016-08-11T03:18:19.7755341Z",
   "endTime": "2016-08-11T03:18:20.2598835Z",
   "trackingId": "bdd82e28-ba2c-4160-a700-e3a8f1a38e22",
   "clientTrackingId": "08587307213861835591296330354",
   "code": "NotFound",
   "status": "Failed"
}

この記事の前出の式を使用することで、さまざまな例外処理パターンを実行できます。To perform different exception handling patterns, you can use the expressions previously described in this article. フィルターで抽出したエラーの配列全体を、スコープ外の単一の例外処理アクションに渡して実行してもかまいません。その場合、For each アクションは不要です。You might choose to execute a single exception handling action outside the scope that accepts the entire filtered array of failures, and remove the For each action. 前述した @result() の応答には、他にも便利なプロパティがあるので、それらを含めることもできます。You can also include other useful properties from the @result() response as previously described.

Azure Diagnostics とメトリックAzure Diagnostics and metrics

ここで取り上げたパターンは、発生したエラーや例外を実行中に処理するうえで、きわめて効果的な方法です。しかし実行そのものとは切り離して、エラーを特定し、対応することもできます。The previous patterns are great way to handle errors and exceptions within a run, but you can also identify and respond to errors independent of the run itself. Azure Diagnostics を使用すると、ワークフローで発生したあらゆるイベントを、実行とアクションのすべての状態を含めて、簡単に Azure Storage アカウントや Azure Event Hubs で作成されたイベント ハブに送信できます。Azure Diagnostics provides a simple way to send all workflow events, including all run and action statuses, to an Azure Storage account or an event hub created with Azure Event Hubs.

ログやメトリックを監視したり、それらを好きな監視ツールに発行したりすることによって、実行の状態を評価することができます。To evaluate run statuses, you can monitor the logs and metrics, or publish them into any monitoring tool that you prefer. その中の一つの方法として、すべてのイベントを Event Hubs を介して Azure Stream Analytics にストリーミングすることが考えられます。One potential option is to stream all the events through Event Hubs into Azure Stream Analytics. Stream Analytics では、診断ログから得られる異常、平均値、またはエラーに基づいて適宜必要なクエリを記述できます。In Stream Analytics, you can write live queries based on any anomalies, averages, or failures from the diagnostic logs. Stream Analytics を使用して、キュー、トピック、SQL、Azure Cosmos DB、Power BI などのその他のデータ ソースに情報を送信できます。You can use Stream Analytics to send information to other data sources, such as queues, topics, SQL, Azure Cosmos DB, or Power BI.

次の手順Next steps