回復可能なアプリケーション例外発生時のみ再試行する仕組みに修正したい

UiPath Studio EnterPrise Edition 23.10.0を利用中の者です。

客先でExcelを1行目から読み込んで、繰り返しWebから情報取得するワークフローを開発中です。
メイン処理はFlowCartで作成しています。
添付画像にある、1件分の業務処理の中でTry CatchアクティビティのTry Blockから、Process.xamlを呼び出してDataTableから抽出したDataRow変数を処理しています。
Process.xaml実行中にRetryすれば回復可能なアプリケーション例外(ネットワーク輻輳など)が発生すれば、Catch Blockで受けて、System.Exception変数(exec_SystemException)にexceptionを代入して、
決められた回数再試行する仕組みです。
しかし、現在の仕組みでは回復不可能なアプリケーション例外(セレクタが取得できませんなど)が、Process.xamlで発生しても、Catch Blockで受けて、System.Exception変数(exec_SystemException)にexceptionを代入して、
決められた回数再試行してしまいます。回復可能なアプリケーション例外(ネットワーク輻輳など)発生時のみ再試行する仕組みに修正することは可能でしょうか。
もし可能であれば、有識者の方、具体的な修正方法を分かりやすくご教示ください。


@gorby,

As of now your catch block if checking for System.Exception which is global exception I would say. It will capture all exception types in single catch.

You will have to add specific exception catches like this.
image

I’m not sure about network related exception you are facing but you can add a catch for that also.

Thanks,
Ashok :slight_smile:

I do not think you answered my question properly as well as I already know what you said.
Regards,
Gorby

回復可能なアプリケーション例外(ネットワーク輻輳など)発生時のみ再試行する仕組みに修正することは可能でしょうか。

@gorby,

Capture the exception in a variable outside of try catch scope to outer scope.

Use Flow Decision and condition like this: varException isnot Nothing

Thanks,
Ashok :slight_smile:

例外の種類(大別すると「再実行で解消する可能性のある例外」と「再実行で解消する可能性のない例外」)によって、処理をリトライするか否かを区別したい、という要望と理解しました。

  • 1枚目の画像のフロー条件分岐「例外発生したか」の分岐条件はどのようになっていますか。
  • 2枚目の画像のTryブロックを実行して「再実行で解消する可能性のある例外」が発生したとき、その例外の型はワークフロー内で Catchブロックの1つ目で指定されている例外の型(画像ではBusinessRuleException)と一致していますか。

Unfortunately, your suggestion does not work in our flowchart because if Not(varException IsNot Nothing), process will count up record counter(the red rectangle in the picture ) and pick up next record.

回答ありがとうございます。ご質問に回答させていただきます。

>* 1枚目の画像のフロー条件分岐「例外発生したか」の分岐条件はどのようになっていますか。

添付画像をご覧ください。exec_SystemExption Is Nothing がTrueの場合は次のレコードを読みに行きます。

>* 2枚目の画像のTryブロックを実行して「再実行で解消する可能性のある例外」が発生したとき、その例外の型はワークフロー内で Catchブロックの1つ目で指定されている例外の型(画像ではBusinessRuleException)と一致していますか。

一致していないと思います。
本件に関連し1点質問をさせてください。

1.Process.xaml内で「再実行で解消する可能性のある例外」が発生した場合、プログラマがThrowしていなくても、且つProcess.xaml内でexec_SystemExption(System.Exception変数)を定義していなくても、Try Catchが自動でこれを認識し自動でThrowして、Catch BlockのSystem.Exceptionフィールドに処理が渡ると推測していますが、正しいでしょうか。

共有されている画像を読むと、下記のように実装されています。

  • Process.xaml を実行したときに BusinessRuleException が発生したら、再試行しない
  • Process.xaml を実行したときに 上記以外の例外が発生したら、再試行する

もし例外の種類ごとに「再試行する/しない」が明確に判断できるのであれば、Catchブロックはそれぞれの例外をキャッチするようにして、かつ再試行の有無(=exec_SystemExceptionへの格納の有無)を適切に実装するのが良いと思います。


Process.xaml の実装に依るところも大きいのですが、Process.xaml 内に一切の例外処理がないことを想定して回答します。

「再実行で解消する可能性のある例外」以外も対象になります。

これは概ね正しいと思います。

例外をスローするのは Try-Catch アクティビティではなく、Try ブロックに含まれるアクティビティです。

Try-Catchアクティビティは、Tryブロックに含まれるアクティビティが例外を発生させたとき、その例外の型にマッチする例外の型(複数ある場合は例外の型の指定がより厳密であるもの)がCatchブロックで指定されていれば、そのCatchブロックの処理を実行する、というものです。
Catchブロックに System.Exception以外の例外の型(仮にAとします)が指定されている場合で、発生した例外の型がAであれば、A を指定しているCatchブロックの処理がなされます。

ここで、悩んでいます。
やりたいことはワークフロー内でのTraffic congestion発生によるWebページクリック不可の検出なのですが、 例えば、すべてのクリックボタンのタイムアウト設定時間を3秒に設定して、Check stateアクティビティを使用して、クリック後3秒経過後に次ページに遷移しない場合は、TimeoutExceptionをThrowするやり方が考えられますか?汎用的なSystem.Exceptionは避けたいです。

そのような実装も問題ないと思います。その場合でしたら、TimeOutExceptionをキャッチできるよう Try-Catch アクティビティを設定したうえで、ワークフロー上の再試行の条件に合致するよう Catchブロックを実装する、ということになるかと思います。

システムを変更して、ネットワークの混雑などの回復可能なアプリケーション例外が発生した場合のみリトライするようにするには、次の手順に従います。

  1. 回復可能な例外の特定: まず、回復可能な例外の種類を特定する必要があります。これらは、リトライすることを望む例外の種類です。

  2. 例外のタイプを確認: Process.xaml内のTry CatchアクティビティのCatchブロックで、捕捉された例外のタイプを確認するための条件を追加します。例外が回復可能なタイプであれば、リトライを続行します。そうでない場合は、リトライせずに例外を適切に処理します。

  3. リトライロジックの実装: 例外が回復可能である場合、Catchブロック内でリトライロジックを実装します。これには、特定の回数リトライするためのループの使用や、自動化フレームワークが提供する組み込みのリトライメカニズムの使用が含まれる場合があります。

以下は、擬似コードでの基本的な例です:

Try
    {
        // ここにメインプロセスのコードを記述します
    }
Catch (Exception ex)
    {
        if (IsRecoverableException(ex))
        {
            // ここにリトライロジックを記述します
            int retryCount = 0;
            while (retryCount < maxRetries)
            {
                try
                {
                    // ここでメインプロセスのコードをリトライします
                    // 必要に応じてリトライ回数を増やします
                    retryCount++;
                }
                catch (Exception retryEx)
                {
                    // 必要に応じてリトライ時の例外を処理します
                }
            }
        }
        else
        {
            // 回復不能な例外をここで処理します
        }
    }

この擬似コードでは、

  • IsRecoverableException(ex) は、例外 ex が回復可能かどうかをチェックする関数です。
  • maxRetries は、操作をリトライする最大回数です。

このアプローチを、ご利用の特定のワークフローやツール、プログラミング言語に合わせて適応させてください。例外を適切に処理し、無限のリトライループを避けるようにしてください。また、リトライ試行によるシステムの過負荷を防ぐために、バックオフ戦略の実装を検討してください。

Hi, Thank you for your reply!
Upon viewing your advice, I understood your advice is correct over all.
However, as you may not aware, your description is too abstract to understand even your suggested code.
Could you translate your advice to concrete example using some concrete case?