uniface.hub

ユニフェイスの開発者ブログ


Title 【Power Automate】例外処理の実装方法
  • 2022年11月28日
  • 上村晃史
【Power Automate】例外処理の実装方法

はじめに

こんにちは、ユニフェイスの上村です!
前回 【Power Automate】Tips まとめ の記事を書きましたが、追加で今回は例外処理(Try-Catch-Finally)の実装方法について纏めます。
Automate にはあらかじめ「例外処理」として用意されているわけではないので、どのように実現できるかを説明します。

基本的なフローの流れ

先ずは「Try」「Catch」「Finally」と3つの【スコープ】を用意して順に並べます。
Try の中にはメインの処理を記述し、Finally には毎回必ず処理したい内容を記述します。

実行条件の構成

Automate で例外処理を実現する上で重要な設定が「実行条件の構成」です。
スコープの三点リーダを押して、上記をメニューから選択します。

通常は「に成功しました」にデフォルトでチェックが入っていますが、そのチェックを外して、「に失敗しました」(必要に応じて「がタイムアウトしました」)のチェックを入れて「完了」を押します。

上記を設定すると、Try と Catch のスコープを繋ぐ矢印が赤色に変わります。
これにより、Try 内でエラー/タイムアウトが発生すると Catch に処理が流れるようになります。

Finally も同様の手順で4つ全てのチェックを入れます。

Catch スコープ内の実装

下記の流れのそれぞれの要素について説明します。

URLの生成

例外が発生したフローの「詳細画面」と「実行履歴詳細」画面に遷移するURLを生成します。

[詳細画面イメージ]

[実行履歴詳細画面イメージ]

「組み込み -> データ操作 -> 作成」アクションを2つ追加して、それぞれ以下の内容を入力することで、上記画面に遷移するURLを生成できます。

https://make.powerautomate.com/manage/environments/@{workflow()['tags']['environmentName']}/flows/@{workflow()['name']}/details
https://make.powerautomate.com/manage/environments/@{workflow()['tags']['environmentName']}/flows/@{workflow()['name']}/runs/@{workflow()['run/name']}

エラー内容の解析

「組み込み -> コントロール -> Apply to each」アクションを追加して、「以前の手順から出力を選択」の箇所に【result(‘Try’)】を指定します。これにより、Try スコープで発生した複数のエラー情報に対して処理できます。

また、その中に「組み込み -> データ操作 -> JSON の解析」アクションを追加します。
「コンテンツ」には動的なコンテンツから【現在のアイテム】を選択してください。
そして「スキーマ」には下記の内容を入力します。

{
    "type": "object",
    "properties": {
        "name": {
            "type": "string"
        },
        "inputs": {
            "type": "object",
            "properties": {
                "host": {
                    "type": "object",
                    "properties": {
                        "apiId": {
                            "type": "string"
                        },
                        "connectionReferenceName": {
                            "type": "string"
                        },
                        "operationId": {
                            "type": "string"
                        }
                    }
                },
                "parameters": {
                    "type": "object",
                    "properties": {
                        "dataset": {
                            "type": "string"
                        },
                        "table": {
                            "type": "string"
                        },
                        "id": {
                            "type": "integer"
                        }
                    }
                }
            }
        },
        "outputs": {
            "type": "object",
            "properties": {
                "statusCode": {
                    "type": "integer"
                },
                "headers": {
                    "type": "object",
                    "properties": {
                        "Vary": {
                            "type": "string"
                        },
                        "X-SharePointHealthScore": {
                            "type": "string"
                        },
                        "X-MS-SPConnector": {
                            "type": "string"
                        },
                        "X-SP-SERVERSTATE": {
                            "type": "string"
                        },
                        "DATASERVICEVERSION": {
                            "type": "string"
                        },
                        "SPClientServiceRequestDuration": {
                            "type": "string"
                        },
                        "X-DataBoundary": {
                            "type": "string"
                        },
                        "X-1DSCollectorUrl": {
                            "type": "string"
                        },
                        "X-AriaCollectorURL": {
                            "type": "string"
                        },
                        "SPRequestGuid": {
                            "type": "string"
                        },
                        "request-id": {
                            "type": "string"
                        },
                        "MS-CV": {
                            "type": "string"
                        },
                        "Strict-Transport-Security": {
                            "type": "string"
                        },
                        "X-FRAME-OPTIONS": {
                            "type": "string"
                        },
                        "Content-Security-Policy": {
                            "type": "string"
                        },
                        "MicrosoftSharePointTeamServices": {
                            "type": "string"
                        },
                        "X-Content-Type-Options": {
                            "type": "string"
                        },
                        "X-MS-InvokeApp": {
                            "type": "string"
                        },
                        "Timing-Allow-Origin": {
                            "type": "string"
                        },
                        "x-ms-apihub-cached-response": {
                            "type": "string"
                        },
                        "x-ms-apihub-obo": {
                            "type": "string"
                        },
                        "Cache-Control": {
                            "type": "string"
                        },
                        "Date": {
                            "type": "string"
                        },
                        "P3P": {
                            "type": "string"
                        },
                        "X-AspNet-Version": {
                            "type": "string"
                        },
                        "X-Powered-By": {
                            "type": "string"
                        },
                        "Content-Length": {
                            "type": "string"
                        },
                        "Content-Type": {
                            "type": "string"
                        },
                        "Expires": {
                            "type": "string"
                        },
                        "Last-Modified": {
                            "type": "string"
                        }
                    }
                },
                "body": {
                    "type": "object",
                    "properties": {
                        "status": {
                            "type": "integer"
                        },
                        "message": {
                            "type": "string"
                        }
                    }
                }
            }
        },
        "startTime": {
            "type": "string"
        },
        "endTime": {
            "type": "string"
        },
        "trackingId": {
            "type": "string"
        },
        "clientTrackingId": {
            "type": "string"
        },
        "clientKeywords": {
            "type": "array",
            "items": {
                "type": "string"
            }
        },
        "code": {
            "type": "string"
        },
        "status": {
            "type": "string"
        },
        "error": {
            "type": "object",
            "properties": {
                "code": {
                    "type": "string"
                },
                "message": {
                    "type": "string"
                }
            }
        }
    }
}

ちなみにこのスキーマの内容については、エラー発生時の「コンテンツ」の内容をコピーしておき、「JSON の解析」アクションの【サンプルから作成】に貼り付けることで生成できます。

[エラー発生時のコンテンツ内容例]

[サンプルから作成するときの入力例]
※ 上記コンテンツの内容を貼り付けて「完了」を押します。

ただし、エラーの内容によって JSON の内容も変わるので、上記で記載したスキーマはある程度のエラー内容ならカバーできるように盛り盛りにしてあります。

失敗判定

エラー内容を解析できたところで次は、その内容から処理に失敗しているかどうかを判定します。(ループ処理の名前を分かりやすく「Error Results Loop」としたものの、よく考えたらエラーで無いものも含まれるため、もう少し実態に合った名前にした方がいいかも・・・)

「組み込み -> コントロール -> 条件」アクションを追加して、左辺には「動的なコンテンツ」から【status】を選択してください。(status は2種類ありますが、下記イメージのように【body(‘JSON_の解析’)?[‘status’]】の方を選択してください)
そして右辺には【Failed】を入力してください。(文字列ですが、ダブルやシングルクオートの括りは不要)

エラー通知(メール送信の例)

失敗判定が「はい」の方にエラーを通知する処理を追加します。
例では「メールの送信」としていますが、Teams への通知といった処理でもいいと思いますので、ご自由に処理を追加してください。

今回は「標準 -> Office 365 Outlook -> メールの送信 (V2)」アクションを追加します。

【本文】の内容をコピーしたものを下記に貼り付けておきます。

フロー名  : @{workflow()?['tags']?['flowDisplayName']}
アクション名: @{body('JSON_の解析')?['name']}
ステータス : @{body('JSON_の解析')?['status']}
エラー内容 : @{body('JSON_の解析')?['code']}
@{body('JSON_の解析')?['outputs']?['body']?['message']}
@{body('JSON_の解析')?['error']?['message']}

【フローの詳細画面の URL】:
@{outputs('フローの詳細画面の_URL')}

【フローの実行履歴詳細の URL】:
@{outputs('フローの実行履歴詳細の_URL')}

[存在しないリストを更新したときの通知内容例]

[0除算したときの通知内容例]

終了処理

最後に「組み込み -> コントロール -> 終了」アクションを追加します。
自分は特に何もしていませんが、必要に応じてカスタマイズしてみてください。

この後は Finally のスコープに処理が移りますが、自分は特に何も処理していないので、こちらも必要に応じて処理を追加してください。不要なら Finally スコープ自体消してしまってもいいと思います。

さいごに

今回紹介した例外処理はテンプレートとしても公開されています。

ただし上記テンプレートだと物足りないので、色々なものを参考に自作してみました。
いまのところ例外処理を実装したいフローには全て上記の処理を入れてあるので、共通化する方法がないか、もしくは今後のアップデートで出来るようになるといいなぁと思います。

参考URL