Apps Script example · 8 min read

Send Error Email Alert: Copy-Paste Apps Script Pattern

Working send error email alert example in Apps Script—copy-paste code, common mistakes, and when to get it built professionally.

MailAppAlertingTriggers

Trigger failures are easy to miss unless someone watches the Executions page. Email alerts close that gap.

sendErrorEmailAlert_ formats a plain-text message with function name, timestamp, effective user, and stack.

runNightlySync demonstrates the try/catch around syncPartnerApi_ and rethrows after mailing.

Set ALERT_TO to a group inbox; authorize MailApp on first run.

Need this built? Hire a Google Apps Script developer →

Sheet / project setup

ItemValuePurpose
ALERT_TOops@example.comRecipient
EntryrunNightlySyncTrigger target
MailAppsendEmailDelivery
Partner/healthSample failure source

What this script does

On failure, ops receives an email then the error propagates.

Prerequisites

Mail send quota; ALERT_TO reachable; UrlFetch if using the sample sync.

  • Authorize MailApp
  • Use a group address
  • Avoid emailing on every row in a loop

Walkthrough

Point health URL at a 500, run runNightlySync, confirm inbox + failed execution.

Edge cases

MailApp daily quotas can exhaust during outages — add CacheService cooldown per fnName.

  • GmailApp alternative for from-alias needs
  • HTML bodies via htmlBody optional

How to test

Throw new Error('test alert') inside the try block.

Hardening for production

Dedupe alerts for 30 minutes; include spreadsheet URL in the body.

Variations

Post to Chat webhook instead of or in addition to email.

Full code: sendErrorEmailAlert_()

Set ALERT_TO, attach a time-driven trigger to runNightlySync, and authorize MailApp once.

/**
 * Email an alert when a guarded operation fails.
 */
const ALERT_TO = "ops@example.com";

function runNightlySync() {
  try {
    syncPartnerApi_();
  } catch (err) {
    sendErrorEmailAlert_("runNightlySync", err);
    throw err;
  }
}

function sendErrorEmailAlert_(fnName, err) {
  const subject = "[Apps Script ALERT] " + fnName + " failed";
  const body =
    "Function: " + fnName + "\n" +
    "When: " + new Date().toISOString() + "\n" +
    "Effective user: " + Session.getEffectiveUser().getEmail() + "\n" +
    "Message: " + (err && err.message ? err.message : err) + "\n\n" +
    "Stack:\n" + (err && err.stack ? err.stack : "(none)") + "\n";

  MailApp.sendEmail({
    to: ALERT_TO,
    subject: subject,
    body: body,
  });
}

function syncPartnerApi_() {
  const resp = UrlFetchApp.fetch("https://api.example.com/health", { muteHttpExceptions: true });
  if (resp.getResponseCode() !== 200) {
    throw new Error("Partner health check HTTP " + resp.getResponseCode());
  }
}
  1. Line 4: Ops inbox or group that should wake up.
  2. Line 10: Builds subject/body and sends mail.
  3. Line 20: Shows which account the trigger runs as.
  4. Line 24: Sends the plain-text alert.
  5. Line 8: Sample dependency that can fail.
  6. Line 11: Preserves failed execution status.

Deploy this example

  1. 01

    Open Apps Script

    In the bound spreadsheet: Extensions → Apps Script. For standalone projects, create one at script.google.com and link your Sheet by ID.

  2. 02

    Paste and save

    Add a .gs file, paste the code below, rename constants at the top (sheet names, column letters, API property keys), then save.

  3. 03

    Authorize once

    Run the main function from the editor. Accept OAuth scopes when prompted — triggers cannot run until authorization succeeds once.

  4. 04

    Add the trigger

    Triggers → Add trigger → choose the handler function and event (time-driven, on edit, or on form submit). Delete test triggers before production.

Before you run: email alerts

  • 1ALERT_TO is a monitored inbox
  • 2MailApp authorized
  • 3Trigger installed on runNightlySync
  • 4Cooldown strategy if errors can flap
  • 5No secrets in email bodies
  • 6Test with a deliberate throw

Frequently asked questions

MailApp is simple for alerts. GmailApp is better when you need labels, aliases, or threads.

So the Executions list shows failure and retries/policies can react.

Use a cooldown key in CacheService or switch to Chat/PubSub for high volume.

Yes — set cc or pass a comma-separated to list.

Mail sends as the effective user unless you configure a send-as alias with GmailApp.

CacheService.getDocumentCache().get(fnName) — skip mail if present; put with 3600 TTL after send.

Add htmlBody alongside body for formatted stacks.

Related examples

Want this wired into your real workflow?

I adapt these patterns to your Sheet structure, APIs, and triggers — deployed in your Google account. Fixed-scope quotes from $500 · free 30-min consult · quote within 24 hours.