GASで自動化を作って、トリガー(=決めた時間に関数を自動で動かす設定)で毎日動かす。最初の数日はうまくいっていたのに、ある日ふと見たら1週間前から止まっていた……。これ、自動化あるあるですよね。
私も、シート名をちょっと変えただけで毎朝の処理がこっそり失敗し続けていたことがあります。トリガーで動く処理は画面にエラーが出ないので、気づける仕組みを最初から入れておくのが大事なんです。
GASの処理を try/catch で包み、失敗したら「いつ・何が・どこで」起きたかをメールで知らせる仕組みを作ります。
通知先のアドレスはスクリプトプロパティから読み込み、コードには書きません。Google標準の失敗通知メールとの使い分けもあわせて整理します。
この記事の前提
- GASの関数をトリガーで動かしたことがある、または動かす予定がある
- トリガーの付け方は GASを毎日自動で動かす|時間主導型トリガーの設定手順 で解説しています
- 例ではスプレッドシートに紐づいたスクリプトを使います
用語メモ
| 用語 | ざっくりした意味 |
|---|---|
| try/catch | 「試しにやってみて、失敗したらこっちを実行」と書ける構文 |
| 例外(エラー) | 処理の途中で起きた問題。放っておくと処理はそこで止まる |
| スタック | エラーが起きるまでに通った関数と行番号の記録 |
| 実行数 | GASのエディタ左側にある、過去の実行結果と状態の一覧画面 |
結論:Google標準の通知+自前の通知メールの二段構え
まず知っておきたいのは、GASには最初から失敗通知の仕組みがあることです。公式ドキュメントによると、トリガーで動いた処理が失敗すると、画面にはエラーが出ない代わりに、Apps Scriptから失敗の概要メールが届きます。送信元は [email protected] です。
ただ、この標準の通知は受け取る頻度の設定によってはまとめて届き、中身も失敗の概要が中心です。そこで、
- 処理を
try/catchで包み、失敗した瞬間に自分の通知メールを送る - 通知を送ったらエラーをもう一度投げ直す(標準の通知と「実行数」の記録も残すため)
の二段構えにします。
手順1:通知先をスクリプトプロパティに登録する
- エディタ左側の「プロジェクト設定」(歯車のアイコン)を開く
- 「スクリプト プロパティを追加」をクリックする
- 「プロパティ」に
NOTIFY_TO、「値」に通知を受けたいアドレス(例:[email protected])を入れる - 「スクリプト プロパティを保存」をクリックする
手順2:通知つきで処理を動かすコードを貼る
次のコードを貼り付けて保存します。dailyJob が本来やりたい処理(ここでは例として「log」シートに1行書くだけ)で、トリガーには main を設定します。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
// トリガーにはこの関数を設定する
function main() {
runWithNotify_('毎朝のログ記録', dailyJob);
}
// 本来やりたい処理(例:logシートに1行追加)
function dailyJob() {
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('log');
if (!sheet) throw new Error('シート「log」が見つかりません');
sheet.appendRow([new Date(), 'dailyJob OK']);
}
// 処理を実行し、失敗したら通知してからエラーを投げ直す
function runWithNotify_(jobName, fn) {
try {
fn();
} catch (e) {
notifyError_(jobName, e);
throw e; // 投げ直すと「実行数」に失敗が残り、Google標準の通知も届く
}
}
function notifyError_(jobName, e) {
const tz = Session.getScriptTimeZone();
const now = Utilities.formatDate(new Date(), tz, 'yyyy/MM/dd HH:mm:ss');
const message = (e && e.message) ? e.message : String(e);
const body = [
`「${jobName}」でエラーが起きました。`,
'',
`日時:${now}`,
`メッセージ:${message}`,
'',
'詳細(どの関数の何行目か):',
(e && e.stack) ? e.stack : '(記録なし)',
'',
`スクリプトを開く:https://script.google.com/home/projects/${ScriptApp.getScriptId()}/edit`,
].join('\n');
console.error(body); // メールが送れなくても「実行数」のログに残す
const to = PropertiesService.getScriptProperties().getProperty('NOTIFY_TO');
if (!to) {
console.error('NOTIFY_TO が未設定のため、通知メールは送っていません');
return;
}
try {
MailApp.sendEmail(to, `【GASエラー】${jobName}:${message}`, body);
} catch (mailError) {
// 通知メール自体の失敗で、元のエラーが隠れないようにする
console.error(`通知メールの送信にも失敗しました:${mailError.message}`);
}
}ポイントを補足しますね。
-
e.messageはエラーの短い説明、e.stackはどの関数の何行目で起きたかの記録です。両方あると、メールを見ただけで原因の見当がつきます -
console.errorで書いた内容は、左側の「実行数」から該当の実行を開くと確認できます - 通知メールの送信でさらにエラーが起きても、元のエラーを隠さないように、送信部分も
try/catchで包んでいます - 本来の処理が複数あるなら、
runWithNotify_('別の処理名', 別の関数)のように使い回せます
手順3:わざと失敗させて通知を確かめる
通知の仕組みは、本当に失敗したときに初めて動くので、事前に1回試しておきましょう。いちばん簡単なのは、「log」シートの名前を一時的に「log_old」などに変えてから、main を手動で実行する方法です。
- シート名を「log」から「log_old」に変える
- エディタで
mainを選んで「実行」を押す(初回は承認の画面が出るので許可する) - 「シート「log」が見つかりません」というエラーで止まり、通知メールが届くことを確認する
- シート名を「log」に戻す
なお、エディタから手動で実行したときは、Google標準の失敗通知は届きません。標準の通知の対象は、トリガーで動いたときの失敗です。この手順で届くのは自前の通知メールだけ、と考えてください。
最後に、トリガーの実行する関数を main にしておけば完成です。トリガーの設定画面では、Google標準の失敗通知をどの頻度で受け取るかも選べます。すぐ気づきたいなら、いちばん早く届く設定にしておくのがおすすめです。
自分の処理に組み込むときは、AIにこう頼むとスムーズです。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
次のGoogle Apps Scriptに、エラー通知の仕組みを組み込みたいです。
【条件】
- 本来の処理は runWithNotify_('処理名', 関数) の形で呼び出す
- 失敗したら notifyError_ で通知メールを送り、そのあと throw e で投げ直す
- 通知先はスクリプトプロパティ NOTIFY_TO から読む(コードに書かない)
- APIキーなどの秘密の値はメール本文に入れない
【通知の仕組みのコード】
(runWithNotify_ と notifyError_ を貼る)
【組み込みたい処理のコード】
(ここに貼る)try/catch では拾えない失敗もある
ここは勘違いしやすいところです。try/catch は万能ではありません。
| 失敗の種類 | try/catchで拾える? | 気づく方法 |
|---|---|---|
| シートが見つからない、値がおかしいなどの実行中のエラー | 拾える | 自前の通知メール |
| 1回の実行時間の上限(6分)を超えて打ち切られた | 拾えないことがある | Google標準の失敗通知、「実行数」 |
| 書き間違いでコード全体が読み込めない(構文エラー) | 拾えない | Google標準の失敗通知、「実行数」 |
| トリガーがそもそも動いていない(削除・作成ミス) | 拾えない | 「トリガー」画面を定期的に確認する |
だからこそ、Google標準の失敗通知は切らずに残しておくのがおすすめです。自前の通知は「すぐ・詳しく」、標準の通知は「最後の砦」という役割分担ですね。
つまずきやすい点
私が最初にやったミスは、catch の中で通知メールを送って満足し、throw e を書き忘れたことです。こうすると「実行数」では成功扱いになり、標準の通知も来ません。あとから履歴を見ても失敗がわからず、かなり困りました。
| 症状 | 原因 | 対処 |
|---|---|---|
| 通知メールが来ない | NOTIFY_TO が未設定、または名前が違う | 「実行数」のログに「NOTIFY_TO が未設定」と出ていないか見る |
| 失敗したのに「実行数」で成功になっている | catch でエラーを投げ直していない | throw e; を入れる |
| 通知が大量に届く | 1分おきなど短い間隔のトリガーで、同じエラーが毎回起きている | 先に原因を直す。必要なら間隔を広げる |
| メール本文に見られたくない値が入った | エラー文に秘密の値を含めている | APIキーやパスワードはエラー文やログに出さない |
| 通知メールも送れていない | 1日に送れる宛先数の上限(個人のGoogleアカウントは1日100件)に達した | 公式の割り当て表を確認し、通知の回数を減らす |
届いたエラーメッセージの意味がわからないときは、そのままAIに渡してしまいましょう。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
Google Apps Scriptのトリガー処理で、次のエラー通知が届きました。
【エラーメッセージ】
(e.message の部分を貼る)
【スタック】
(e.stack の部分を貼る。メールアドレスやIDなど個人の情報は伏せる)
【処理の内容】
毎朝、スプレッドシートの「log」シートに1行追加するだけの処理です。
原因として考えられることと、確認する順番を教えてください。まとめ
- トリガーで動く処理はエラーが画面に出ない。だから「気づける仕組み」を先に入れる
-
try/catchで通知メールを送り、throw eで投げ直して記録と標準通知も残す - 時間切れや構文エラーは拾えないので、Google標準の失敗通知と「実行数」も併用する
次の一歩は、いま動かしている自動化を1つ選び、runWithNotify_ で包んでから、わざと失敗させて通知が届くか試してみることです。1回届けば、「止まっていたのに気づかない」不安からかなり解放されますよ。
関連する本・記事
GASの自動化を「作って終わり」ではなく、毎日安心して動かしたい方は、『Google Apps Script × 生成AI 全自動仕事術』も参考になります。生成AIに頼みながら、GASで仕事を自動化していきたい方向けの1冊です。
- トリガーの付け方から確認したい方へ:GASを毎日自動で動かす|時間主導型トリガーの設定手順
- ログを別のシートに残したいなら:GoogleAppsScriptのログを別ファイルか別のスプレッドシートに書き出す方法
- サーバーの停止にも気づきたいなら:サーバーが止まったら知らせる|Linuxの死活監視とn8n通知の入門【初心者向け】
- GASを順番に学びたい方へ:GAS学習の進め方|既存記事をつなぐ学習マップ
- メンバーのKindle本の一覧:biliotechまわりのKindle著書リスト