0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

GASでProxyを使ってリトライ処理する

0
Posted at

経緯

GASで外部APIを叩くときUrlFetchAppを一般的に用いるが、これのリトライ処理をする場合、try-catchで囲んでUtilities.sleep()して〜と書いていると、コードが長くなってしまうので、JavascriptのProxyで効率化してみました。

コード

function createRetryProxy(target, maxRetries = 3, waitMs = 1000) {
  return new Proxy(target, {
    get(target, prop) {
      const original = target[prop];

      if (typeof original !== 'function') {
        return original;
      }

      return (...args) => {
        let cnt = 0;

        while (cnt < maxRetries) {
          try {
            return original.apply(target, args);
          } catch (e) {
            cnt++;
            console.warn(`Proxy Warn: ${prop.toString()} (${cnt}/${maxRetries}): ${e.message}`);

            if (cnt > maxRetries) {
              console.error(`The maximum number of retries has been reached.`);
              throw e;
            }

            Utilities.sleep(waitMs * cnt);
          }
        }
      };
    }
  });
}

function testRetryProxy() {
  const WrappedUrlFetchApp = createRetryProxy(UrlFetchApp, 3, 2000);

  try {
    // DNSエラー
    const response = WrappedUrlFetchApp.fetch("http://localhost:8080");

    console.log(response.getContentText());
  } catch (e) {
    console.log(e.message);
  }
}

簡単な解説

Proxyオブジェクトを生成すると、元のオブジェクトへの操作が行われたとき、操作を傍受したり動作を再定義することができます。get()でトラップして処理を行い、apply()で本物の処理を行う、という流れです。

応用

オブジェクトをProxyでラップして、プロパティの代入時にsetでスプレッドシートに書き込んで、プロパティの読み取り時にgetでスプレッドシートから読み込むといったこともできます。こうすることで、GAS特有の.getRange().setValue()のような長いコードではなく、変数代入のような気軽さでシート操作ができたりします。

function reactiveCell() {
  const spr = SpreadsheetApp.openById("sheetid");
  const sheet = spr.getSheetByName("sheetname");

  const cells = new Proxy({}, {
    get(target, prop) {
      return sheet.getRange(prop).getValue();
    },
    set(target, prop, value) {
      sheet.getRange(prop).setValue(value);
      return true;
    }
  });

  cells.A1 = 42;
  cells.A2 = "hoge";
  console.log(`A1 is ${cells.A1}`);
}

スクリーンショット 2026-03-03 17.56.13.png

おわりに

スパゲッティコードに悩んでるGAS書きの皆様は、ぜひProxyのことを頭の片隅に入れてGASをガスガス書いて欲しいです。

0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?