3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

GoogleAppsScript(GAS)の自動リトライ処理

Last updated at Posted at 2023-03-13

GASでまれに予期しないエラーが起こる

GoogleAppsScript(GAS)は無料で使えて、様々なことができてとても便利です。
ただ、無料で使わせてもらっておいてなんですが、ちょこちょこ予期しないエラーが発生してエラー対応で大変な思いをするときがあります。

たとえば
スプレッドシートの操作時に「スプレッドシートとの接続が切れました。」とエラーになったが、すぐに再実行してみると普通に成功する。。
みたいなことが起きます。

リトライすれば成功するのですが、GASには自動でリトライする処理は用意されていないので
以下のように自分で実装していきます。
・エラーになったら自動でリトライする
・トライ回数は自由に設定できる
・どんなエラーが起きたか分かるようログは出す
・指定回数実行してもエラーになる場合は、通知する

起きたり起きなかったりするエラーを再現

リトライ処理を実装するにあたって、テストしやすいように
起きたり起きなかったりするエラーを再現してみます。

タイムスタンプを取得して、そのタイムスタンプが偶数だったらエラーをスローさせます。

タイムスタンプが偶数だったらエラーをスロー
function main() {
  // タイムスタンプ取得
  const timestamp = Date.now();
  console.log("タイムスタンプ: " + timestamp);

  // タイムスタンプが偶数だったらエラー(起きたり起きなかったりするエラーの代わり)
  if (timestamp % 2 === 0) {
    throw new Error("テストエラー");
  }

  return "成功!!";
}

実際に実行させると
・偶数でエラー発生
image.png

・奇数でエラー発生せず
image.png

このように、タイムスタンプが偶数ならエラー、奇数なら正常終了します。
これをエラーが起きたり起きなかったりするmainの処理に見立てていきます。

GASの自動リトライ処理

GASの自動リトライ処理のコードは以下になります。
const tryCount = 3;の数値を変えるだけで何回トライさせるかを変更することができます。
エラーの通知のさせ方など適宜変更していただければ。

GAS自動リトライ
function retryFunc() {

  // トライ回数の設定
  const tryCount = 3;
  // 指定回数分ループ
  for(let count=1; count < tryCount+1; count++){

    try {
      console.log("トライ回数: " + count);

      // メインの処理を実行
      const result = main();

      // メインが成功したら、処理終了
      console.log(result);
      return;

    // エラーが発生した場合
    } catch (e) {

      // トライ回数分リトライ
      if (count < tryCount) {
        console.warn(e.stack);
        console.warn("予期せぬエラーが発生したためリトライします。");
        continue;
      }

      // 以下、トライ回数実行しても成功しない場合エラー通知
      console.error(e.stack);
      console.error(tryCount + "回トライしても成功しませんでした。");
      // ここに、メールやらSlack通知を入れて通知して処理終了
      console.log("**** エラー通知の代わり ****");

    }
  }
}

1回で成功した場合

エラーなっていないのでcatchに入らずそのままreturnで処理が終了します。
image.png

1回目はエラー、2回目で成功した場合

1回目でエラーになりcatchに入りif (count < tryCount)がcountが 1, tryCountが3なのでif文に入りcontinueされます。
2回目はエラーにならずcatchに入らないためreturnで処理が終了します。
「2回目もエラー、3回目で成功」も同様です。
image.png

3回ともエラー

1, 2回目でリトライされて、3回目もエラーになった場合はif (count < tryCount)がcountが 3, tryCountが3となり、if文に入らずエラー通知されます。
image.png

コピペ用

ご自身のGASエディタにコピペできるようコード全体をのせます。
retryFunc()を実行して挙動の確認してみてください。

function retryFunc() {

  // トライ回数の設定
  const tryCount = 3;
  // 指定回数分ループ
  for(let count=1; count < tryCount+1; count++){

    try {
      console.log("トライ回数: " + count);

      // メインの処理を実行
      const result = main();

      // メインが成功したら、処理終了
      console.log(result);
      return;

    // エラーが発生した場合
    } catch (e) {

      // トライ回数分リトライ
      if (count < tryCount) {
        console.warn(e.stack);
        console.warn("予期せぬエラーが発生したためリトライします。");
        continue;
      }

      // 以下、トライ回数実行しても成功しない場合エラー通知
      console.error(e.stack);
      console.error(tryCount + "回トライしても成功しませんでした。");
      // ここに、メールやらSlack通知を入れて通知して処理終了
      console.log("**** エラー通知の代わり ****");

    }
  }
}


function main() {
  // タイムスタンプ取得
  const timestamp = Date.now();
  console.log("タイムスタンプ: " + timestamp);

  // タイムスタンプが偶数だったらエラー(起きたり起きなかったりするエラーの代わり)
  if (timestamp % 2 === 0) {
    throw new Error("テストエラー");
  }

  return "成功!!";
}

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?