【UiPath】Retry Scopeの実装例

## 概要
UiPathのRetry Scope（リトライ スコープ）の実装方法です。
具体的な実装ケースを２つ紹介します。

## 前提：Retry Scopeアクティビティの設定方法
基本的な設定方法は以下の通りです。
注意点として、条件セクションに使えるアクティビティは"ElementExists"など一部のものに限ります。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/578020/7fd060df-94a7-5bd0-97db-432bdddedaee.png"  width=80%>

## １．ファイルの移動操作で使う
ファイルの移動はネットワークの一時的な接続不良だったり、直前の処理にファイルを掴まれたままだったりで、
初めはエラーになるけれど、再試行すればうまくいく場合もままあります。

例として、エラーになるよう指定した"CopyFile"をリトライスコープで囲って実行してみましょう。
![シーケンス6.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/578020/6747f661-1038-b927-6c01-1fd2e3ada0df.jpeg)
ここで、条件セクションは必須ではないため、何も指定していません。
この場合は単に「実行セクションでエラーが発生したら再試行する」という動きになります。
![ログ4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/578020/55f8a044-6b22-80d4-e342-d573aaf0708d.png)
5秒ごとに繰り返し実行し、3回目が失敗した時点でエラーになっています。
ここでは全てエラーですが、もちろん途中で成功すればその時点で次の処理に進みます。

なお、エラーになった際に表示されるアクティビティ名は、実行セクションの表示名ではなく、
リトライスコープ自体の表示名であることに注意が必要です。
![エラー1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/578020/ce0bebd5-db27-76fe-bf9a-1d8cd40be729.png)

結果がわかりやすいように上ではログ出力を入れていますが、実際の処理に組み込む場合は以下で十分です。
![リトライ スコープ.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/578020/d41bbb0a-5614-4eac-0db3-eb6aa722080c.jpeg)

## ２．画面遷移で使う
Webやアプリなどで、次の画面に遷移するボタンをクリックしたけれど、
なんらかの理由で空振り、正常に画面遷移しなかったという場合もままあると思います。
この場合もリトライスコープで囲うことで画面遷移するまで再試行するという動きができます。
ただし、後述しますが設定には一部注意が必要です。

例として、Google検索画面でQiitaをクリックして、
Qiitaのトップ画面が表示されるか確認するワークフローを組みます。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/578020/930f6467-60be-c451-2bec-65847b309db3.png" width=40%>
![シーケンス7.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/578020/a14f84b1-e1bc-8f25-dc6e-998f40dd8eea.jpeg)
Googleの検索画面を表示して、組んだワークフローを実行をしてみましょう。
ただし、実行中はマウスカーソルを手でグルグル動かし続けてクリックを空振りさせます。
![エラー2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/578020/018b650e-a9d5-fe48-97e1-051025cc0566.png)
この場合、実行セクションのクリック自体は成功したと認識されますが、
画面遷移は出来ていないので、条件セクションの要素検出でFalseが返り、実行セクションが再試行されています。
条件セクションを満たせずに終了した場合は、<b>Action failed to execute as expected.</b>のエラーが出力されます。

別のパターンとして、Googleの検索画面を表示せずにワークフローを実行してみます。
![エラー3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/578020/f31e148e-bec7-9f36-f973-e22e1e68fe12.png)
同じく実行セクションが再試行されていますが、こちらはクリック自体が失敗しているため、
クリックアクティビティのエラーが出力されています。

正常系も確認してみましょう。
Googleの検索画面を表示して、マウスカーソルは動かさずにロボットの実行を見守ります。
![ログ5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/578020/b5b2586f-2dbf-f403-8a8f-55f2eb05c476.png)
無事に画面遷移に成功し、ワークフローも正常終了しました。

ここまでで動きとしては問題ないように思えますが、<b>実は穴があります。</b>
さらに別のパターンとして、次のような形でロボットを実行させてみます。
・Googleの検索画面を表示してスタート
・マウスカーソルをクルクル動かして1度目のクリックを空振りさせる
・1度目の要素検出が終わってリトライスコープの待機時間に入ったところを見計らい、手動でQiitaのトップ画面に移動する。
![エラー4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/578020/ea7492c4-6ae9-208b-37d8-551db8df8ce0.png)
画面遷移は出来ているのですが、ロボットはそれを検知できずに失敗しています。
<b>実行セクションがエラーをスローすると、条件セクションの判定は行われない</b>ということがわかります。
上のような操作をすることはあまりないでしょうが、
ネットワークが重くて画面の読み込みに時間がかかり、1度目の条件セクション中に画面遷移要素を検知出来なかったが、
画面自体は遷移しているため、実行セクションの再試行でクリックのセレクターが見つからずにエラーをスローする、
というケースは十分あり得ると考えられます。

解決策として、以下のように実行セクション全体をTryCatchで囲みます。
![シーケンス9.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/578020/39f98701-24b4-1b24-71b8-b30a7daf020c.jpeg)
これで実行セクションでエラーが発生してもCatchするため、実行セクションが必ず実行され、
上で書いたようなケースでも画面遷移を検出してくれます。
Catchの中ではエラーログを出しておきましょう。

ここまでで完成形になります。
そこそこ複雑な形になり、エラーが出るタイミング等もよく理解しておく必要がありますが、
使いこなせればロボットをより安定させられるはずです。

### 画面遷移で使う場合：別解
実行セクションに入れるアクティビティが一つの場合は、
TryCatchで囲まず、実行セクション内のアクティビティの"エラー発生時に実行を継続"をTRUEにするでもOKです。
![キャプチャ4.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/578020/edd353de-fa46-1aad-9338-cc9689d5a7a7.jpeg)
この場合、実行セクションのエラーログが出ないためエラー原因を調べにくくなりますが、
TryCatchで囲まないため多少は見た目がシンプルになります。

なお、実行セクションに複数のアクティビティがある場合でも、
全てをエラー時継続にすれば動作上は問題ないですが、どれでエラーが出たかわからなくなる非推奨です。

## 補足：運用上の注意点
リトライスコープに限った話ではないですが、再試行すること自体がリスクにならないか気を付ける必要があります。
例えば、パスワードが間違っているのに何度もログインを試行してしまいアカウントがロックされた、などです。

## まとめ
- ファイルコピーなどのファイル操作系はとりあえずリトライスコープで囲えばエラー時に再試行してくれる。
- Webやアプリで画面遷移が不安定な時は、画面遷移するアクティビティ（クリックとか）をTryCatchとリトライスコープで囲んで、条件セクションに遷移先の要素検知を指定すれば、遷移に失敗しても再試行してくれる。

## 動作環境
- UiPath 2019.9.2 Community Edition