- 2022年11月28日
はじめに
こんにちは、ユニフェイスの上村です!
前回 【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 スコープ自体消してしまってもいいと思います。
さいごに
今回紹介した例外処理はテンプレートとしても公開されています。

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