Automation Anywhere v11におけるエラーハンドリングとログ出力

# 概要
RPAでロボットを作成して実行する場合に、作成時と環境がちがったりすると、想定通りにいつも動くとは限りません。そうするとロボットが頻繁に止まってしまうことにもつながりかねません。

特定の環境を超えて組織内で広くロボットを配布する際には、いろいろな条件を想定したエラー (例外) 処理を入れておくことをお勧めします。ただし、エラー処理の実装にはある程度のプログラミングの知識を必要とします。

この記事では、エラー処理を行うにあたり考慮すべき要素と実際の実装方法についてみていきましょう。

**環境**

* Automation Anywhere Enterprise v11.3.3

# エラー処理コマンドとは
**エラー処理 (Error Handling)**コマンドは、例外が起こった時にその詳細情報を把握して対応できるようにするためのしくみです。

コマンドには「Begin Error Handling」「End Error Handling」の2つがあり、この2つで囲まれた範囲で例外が発生したときに、オプションで指定した特別な処理を実行します。

以下の例では、Excelのファイルを開いてセルの値を取得する処理中に何らかの例外が発生したときに、エラー処理が発動します。(たとえば指定した位置にExcelファイルがない、など)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479715/1df36e8c-0bf5-874a-48bf-04536b2b2bd4.png)

コマンド一覧の中には以下の2つのコマンドが配置されており、アクションリストに「Begin Error Handling」コマンドをドラッグ＆ドロップすると、「End Error Handling」コマンドも一緒にドロップされます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479715/bcd83b04-7217-dea6-3faa-5308b5780a22.png)

その後、以下のダイアログボックスが開いて、オプションの詳細を指定する画面となります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479715/a72c1a52-0e7f-e033-8a09-7dfcf247351c.png)


# オプションの詳細

ダイアログボックスではいろいろなアクションが選択できます。

**Error Handlingアクションを選択**
Error Handlingオプションで指定した内容を実行した後にどうするかを指定します。

* **Continue:** 例外が発生した次の行から実行を再開します。例外が発生しても無視して進める場合は、オプションを何も指定せずにContinueを選びます。後で述べる例外関係のシステム変数を使ってログを出力することもできるので、通常はこちらを選択しておくとよいでしょう。
* **Stop Task:** 例外が発生した行を最後に実行を停止します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479715/dab9ee3b-4f81-80fb-bf54-51cde4956a82.png)

**Error Handlingオプションを選択**
例外発生時に実施する項目を指定します。

* **スナップショット:<font color="Red">【利用お勧め】</font>**例外が起こった時のスクリーンショットを撮ります。ファイル名を指定すると、ファイルに保存します。変数も使えるので、たとえば "`C:\Users\(Username)\Documents\Automation Anywhere Files\LogFiles\$Year$-$Month$-$Day$_$Hour$-$Minute$-$Second$.PNG`"のようなパスを指定しておくと、時間によって重複しないファイルに保存されるのでお勧めです。エラーメッセージが出た画面が撮られるので、何が起こったかを画面で確認することができます。
* **Run Task:**特定のTaskBotを起動します。ただし、TaskBotに引数を引き渡せないので、使いどころは限られるかもしれません。
* **ファイルに記録:<font color="Red">【利用お勧め】</font>**Log To Fileコマンドと同様、指定したファイルに指定したテキストを書き込みます。(既存ファイルへの追加も可能)。ファイル名、内容ともに変数を指定できるので、さまざまなシーンで活用できます。後の「[ログ出力をしよう](#ログ出力をしよう)」の章で、活用方法についてより詳しく触れます。
* **Send Email:**例外が起こった時に指定した宛先にメールを出します。その時の変数の内容一覧やスクリーンショットを添付することができますが、メール本文は記載ができません。
* **変数の割り当て:<font color="Red">【利用お勧め】</font>**指定した変数に任意の値を代入することができます。
* **タスクステータスを設定:**FailまたはPassのいずれかに設定できます。既定はFailです。

# 関連するシステム変数

* `$Error Line Number$`: 例外が発生した行番号が格納されます。例外が発生していない場合は0を返します。
* `$Error Description$`: 発生した例外のエラーメッセージが格納されます。例外が発生していない場合は空白となります。

その他、マシン名などのシステム状態の取得や日付と時刻のシステム変数などが有用です。『[Automation Anywhere 便利なシステム変数一覧](https://qiita.com/RPAbot/items/4f03665cac09dcf6a246)』をご覧ください。

# Begin/End Error Handlingの範囲に注意しよう
ここで`Begin Error Handling`と`End Error Handling`で囲うコマンドの行数や内容に注意しましょう。両者で囲われた範囲でエラーが発生すると、その行でエラー処理が行われ、その後は、Continueオプションの場合、`End Error Handling`の次の行から処理が再開されます。つまり、**エラー発生行の次の行から`End Error Handling`までの間のコマンドは処理がされません。**

冒頭のExcelの例で、3行目でExcelファイルがない場合は、4行目もスキップするのが正解なので、これらはまとめて囲ってしまうのが正解です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479715/1df36e8c-0bf5-874a-48bf-04536b2b2bd4.png)

一方、ExcelコマンドとCSVコマンド、もしくはデータベースコマンド等は独立してエラーが発生する可能性があるため、これらの異なる種類のコマンドは別々に囲いましょう。また、Error Handlingは多重にすることも可能です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479715/396aae88-9829-bd68-d25d-d6f1f80fbcf9.png)


# ログ出力をしよう

### ログ出力の重要性
特に複数人でロボットを共有して開発/運用する場合、ログの出力は重要になってきます。まず、ロボットは開発にかかる労力が10%、そしてサポートとメンテナンスにかかる労力が90%になるといわれています。また、サポートとメンテナンスをする人は開発した人と異なっていること、さらには全然違う部門の人であるということもよくあります。

その場合に、他人が作ったロボットをデバッグするという作業は、プロセスのステップ数にもよりますが、かなり大変な作業となってきます。その際に、例外の発生時刻、発生したマシン名、ロボット名、行番号、例外の内容と説明、変数の状態、スクリーンショットなどが正しく保存されていれば、作業がかなり軽減されます。そのため、開発の段階でこれらの情報を他人にもわかりやすく正確にログを出力するということはとても重要になってくるのです。

### 記録するファイルの種類と場所
ログは以下の形式で以下のような場所に保管しておくことが望ましいです。

* 書き出しが楽であるのと、Excelで読み込んですぐに分析可能であるため、**CSVテキストフォーマット**で出力しておく。
* ログファイルの名前はいつのものかわかりやすいように "Log_YYYY-MM-DD.csv" のような日付と時刻が含まれる形式にしておく。
* 個人情報はログに書き出さないようにする。
* ファイルを書き出す先は共有ネットワークドライブなど、多くの人がアクセス可能な場所にする。

### ログ内容についての要件
ログには以下のような内容を含めるとよいです。

* **タイムスタンプ:** ログの項目が出力された日付と時刻
* **マシン名:** ロボットが実行中のマシン名
* **ロボットのタスク名:** 実行されているタスクの名前
* **プロセスID:** 実行中のタスクプロセスを判別するためのIDのようなものをあらかじめ振っておく
* **行番号:** メッセージが発生した行番号
* **メッセージの分類:** 情報提供、警告、エラーのいずれか
* **メッセージの内容:** 実際のエラーメッセージや状態

```:Log_2020-01-25.csv
Datetime,Type, MachineName, TaskName, ProcessID, LineNumber, Message
"2020-01-25 14:20:00",警告,"Robot001","LogIntoSAP.almx", "qaH4znod7Rex33Y", 4, 
"申し訳ございません。C:\Temporary-Folder\NameList.xlsxが見つかりません。
名前が変更されたか、移動や削除が行われた可能性があります。
Screenshot: C:\Screenshot\2020-01-25_14-10-58.png"
```

### ログ出力をするタイミング

ログに出力すべきタイミングは大きく分類すると以下の3つになります。

1. システムエラーが発生したとき
2. ビジネスプロセス上のエラーが発生したとき
3. 進行状況の節目での追跡

最低限1のケースは実装しましょう。2も重要な例外処理は出力すべきでしょう。3はどこまで出力するか悩みどころで、あまり多くの情報を出力しても埋もれてしまうので、以下のものを目安にするとよいでしょう。

* Bot が開始、または終了/停止したとき
* ケース/発注/項目などの開始時と終了時
* アプリケーションを開いたり閉じたりしたタイミング
    * アプリケーションが想定よりも長く開かれている場合は、30秒毎くらいで経過をログしましょう。


### Automation Anywhereにおける実装

1のケースは、先ほどの**Begin Error Handling**ダイアログボックスの中のログ出力オプションで実装しましょう。[システム変数](https://qiita.com/RPAbot/items/4f03665cac09dcf6a246)からマシン名や日付と時刻は取得が可能です (`$Year$-$Month$-$Day$_$Hour$-$Minute$-$Second$`など)。既存ファイルに追加するオプションを選んでおくとよいです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479715/501b7bc4-460d-d9bc-8504-495d3642e4e5.png)

2、3のケースは**Log To File**コマンドを使いましょう。ファイル名、テキストなどのオプションの記載の仕方は先ほどと同じです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479715/449dcbca-8a50-76c8-a60e-b548e5b2a821.png)


# 参考情報

* [Error Handlingコマンド](https://docs.automationanywhere.com/bundle/enterprise-v11.3/page/enterprise/topics/aae-client/bot-creator/commands/error-handling-command.html?_LANG=jpjp) - 製品ドキュメント