見出し画像

Power Automate Desktopのエラー処理とリトライを入れたら、止まったフローの復旧が月90分→10分になった話

毎朝の自動実行を組んだら、今度は「動いてると思ってたら止まってた」が起きるようになりました。

そこでPower Automate Desktop(PAD)のフローに、アクション単位の「エラー発生時」設定と、ブロック単位のエラー処理を入れました。一時的な失敗は勝手にリトライして復帰、本当にダメなときだけ通知が飛ぶ形です。

結果、月90分かかっていた「止まったフローの復旧」が月10分になりました。気づくまでの時間も、平均5時間から3分になっています。

この記事でわかること

  • PADのアクション単位「エラー発生時」でできること(再試行・分岐・変数の設定)

  • 「ブロック エラー発生時」で複数アクションのエラーをまとめて拾う書き方

  • 再試行してよい失敗と、してはいけない失敗の見分け方

  • エラーを握りつぶして「正常終了」に見えてしまう事故の防ぎ方

1. 何に困っていたか

前回、締切監視のフローをタスクスケジューラで毎朝7時に自動実行するところまで作りました。手を離せるようになって満足していたんですが、そこから別の問題が出てきました。

月に3回くらい、フローが途中で止まっている。 しかも気づくのは昼過ぎに「今日の一覧、来てないんだけど」と言われたときです。

止まる理由を並べてみると、だいたい3パターンでした。

  • 対象のExcelを誰かが開きっぱなしで、ファイルがロックされている

  • 共有フォルダ(ネットワークドライブ)がまだ繋がっていない

  • 元ファイルの列が増えていて、想定した列が見つからない

1回あたり、原因を調べて、手で再実行して、関係者に「遅れます」と連絡して、だいたい30分。月3回で90分です。

しんどいのは時間そのものより、上の2つが「5分後にもう一度やれば普通に通る」やつだったことでした。人間が張り付いて再実行するために自動化したわけじゃないよな、と。

2. 作ったものの構成

やったことは4つです。

  1. 落ちやすいアクション(Excelの起動、ファイルのコピー)に再試行を設定する

  2. フロー全体を**「ブロック エラー発生時」**で囲んで、取りこぼしを拾う

  3. エラーを拾ったらフラグ変数と原因メッセージを残す

  4. 結果をステータスファイルに書き出して、PowerShell側から通知する

アクション単位の「エラー発生時」

PADは、どのアクションの設定ダイアログにも左下に**「エラー発生時」**というボタンがあります。ここを開くと、そのアクションが失敗したときの動きを個別に決められます。

  • 再試行ポリシー:「アクションを再試行する」を選んで、回数と間隔(秒)を指定

  • フロー実行を続行する:「次のアクションに移動」「アクションの繰り返し」「ラベルに移動」

  • 新しいルール:「変数の設定」でフラグを立てる、「フローの実行」で止める

私が入れたのは、「Excelの起動」に対して3回・10秒間隔の再試行です。誰かが開きっぱなしのロックは、だいたいこの30秒のうちに解けます。ネットワークドライブ待ちも同じで、朝イチの数十秒だけの問題なので、待てば通ります。

ブロックでまとめて拾う

個別設定だけだと、想定していなかったアクションで落ちたときに素通りしてしまいます。そこでフローコントロールの**「ブロック エラー発生時」**で本処理をまるごと囲みました。ブロックの中のどのアクションで落ちても、指定した処理に飛ばせます。

構造はこんなイメージです。

On block error(ブロック エラー発生時)
    Excel の起動              ← 再試行 3回 / 10秒
    Excel ワークシートから読み取り
    (締切の判定・一覧の組み立て)
    Excel を閉じる
End
    ↑ ブロック内でエラー → 設定したルールが動く
      ルール1: 変数の設定  ErrorFlag = True
      ルール2: 変数の設定  ErrorNote  = '締切監視ブロックで停止'

エラー時のルールで ErrorFlag を立てて、最後にまとめて後始末します。

If ErrorFlag = True then
    ファイルへのテキストの書き込み: C:\tools\status.txt ← 'NG ' + ErrorNote
    フローの停止(エラーメッセージあり)
Else
    ファイルへのテキストの書き込み: C:\tools\status.txt ← 'OK'
End

PowerShell側(前回タスクスケジューラに登録したps1)は、これを読むだけです。

$statusPath = 'C:\tools\status.txt'
$status = (Get-Content -Path $statusPath -Raw -Encoding UTF8).Trim()

if ($status -ne 'OK') {
    New-BurntToastNotification -Text '締切監視フロー', $status
    exit 1
}

トースト通知は#03で作ったやつをそのまま使い回しています。

3. ハマったところ

PADの再試行が効かない:エラーにならない失敗はリトライされない

症状: 中身が空のExcelを読んでも再試行が1回も走らず、空っぽの一覧がそのまま出来上がって最後まで通ってしまう。

原因: 再試行は「アクションが例外を出したとき」だけ動きます。ファイルは開けた、読み取りも成功した、結果が0行だった——これはPADから見ると成功です。エラーじゃないので、再試行の出番がありません。

解決: 「失敗の定義」は自分で書くしかないです。読み取り直後に件数を判定して、想定外なら「フローの停止」で自分からエラーにします。

If  DataTableの行数 = 0  then
    フローの停止(エラーメッセージ: '読み取り0件。元ファイルを確認')
End

空白行や空セルの扱いは#04でハマったところそのままなので、あわせて読むと早いです。

PADでエラーを握りつぶすと「成功」に見える

症状: 止まるのが嫌で、片っ端から「次のアクションに移動」を設定してみました。たしかに止まらなくなったんですが、今度は失敗しても静かに最後まで走りきって、タスクスケジューラの前回の実行結果も 0x0(成功)のまま。前より状況が悪化しました。

原因: エラー処理は「例外を消す」処理です。消したら、当然どこにも伝わりません。「次のアクションに移動」は、後続が動いても問題ない場合にだけ使うものでした。

解決: 消すなら必ず記録を残す、をルールにしました。エラーのルールで ErrorFlag と原因メッセージを変数に入れ、最後に status.txt へ書き出して「フローの停止」でエラー終了させます。呼び出し側のps1は status.txt を見て通知するので、握りつぶしと通知が両立します。

PADのリトライでデータが二重に入る

症状: 例外処理を「ブロックの繰り返し」にしたら、転記済みの行がもう一度追記されて、一覧に同じ案件が2件並びました。

原因: ブロックの繰り返しはブロックの先頭からやり直しです。途中まで成功していた書き込みは巻き戻ってくれません。

解決: 再試行の範囲は「何回やっても同じ結果になる処理」だけにしました。具体的には、ファイルを開く・読む・接続する、あたりです。書き込み系はリトライの中に入れず、いったん全部データテーブル上で組み立ててから、最後に一括で書き出す形に変えました。こうすると途中で落ちても、書き込みは0件か全件かのどちらかになります。

4. 実際どうなったか

月3回止まっていたうち、ロックとネットワーク由来の2回はリトライで自力復帰するようになりました。残りの1回(列が増えた、みたいな構造の変化)は、朝7時台にトーストで飛んできます。

  • 気づくまでの時間: 平均5時間 → 3分

  • 1回あたりの対応: 30分 → 10分(通知に原因が入っているので、調査がほぼ要らない)

  • 月あたりの復旧時間: 90分 → 10分

数字より効いたのは、「今日は動いたのか?」を気にしなくてよくなったことでした。通知が来なければ動いている、で終わりです。

おわりに

この考え方はPAD以外でもそのまま使えます。PowerShellなら try / catch と再試行ループ、最後にステータスを書き出す。「一時的な失敗は自分で立ち直る」「戻れない失敗は必ず外に叫ぶ」の2つを分けて設計する、というだけの話です。

次回は「自動化スクリプトのログ設計(Transcript)」を書きます。今回さらっと「原因メッセージを残す」と書きましたが、どこに何をどれだけ残すかを先に決めておかないと、いざ落ちたときに手がかりゼロになるので。

役に立ちそうだったら、スキを押してもらえると次を書く力になります。

いいなと思ったら応援しよう!