Your Puppeteer script scraped a critical dashboard and checked a payment flow every six hours. Then a Chrome update changed how headless mode launched, and the script began silently exiting with code 0 before any page loaded. The monitoring data stopped updating. The team noticed — five days later, when someone asked why the dashboard had flatlined.
This is the silent automation failure problem. A Puppeteer script has no built-in "phone home" mechanism. It either runs and you hope it worked, or it doesn't run and you might never know. The fix is heartbeat monitoring: your script pings Vigilmon after each successful run, and Vigilmon alerts you when that ping stops arriving on schedule.
What You'll Cover
- Heartbeat monitoring for scheduled Puppeteer scripts
- Catching Puppeteer processes that exit silently or hang
- Detecting Chromium/Chrome launch failures
- Multi-script monitoring for different automation tasks
- Alerting on scripts that time out or navigate to the wrong page
Prerequisites
- A Puppeteer script (version 19+, or using
puppeteer-core) - A free account at vigilmon.online
The Problem: What Standard Puppeteer Error Handling Misses
Puppeteer throws errors you can catch — but alerting you when no one invokes it at all is not Puppeteer's job. You're silently exposed when:
- The cron job or scheduled task running Puppeteer is deleted or misconfigured
- Chromium fails to launch (GPU driver, sandboxing, missing libs) and the process exits 0
- The script hangs indefinitely waiting for a selector that no longer exists
- A network timeout silently swallows the page load and the script exits cleanly
- A Node.js version upgrade breaks the
puppeteernative module and the process crashes without alerting anyone
Vigilmon's heartbeat pattern closes all of these gaps.
Step 1: Create a Heartbeat Monitor in Vigilmon
- Log in to Vigilmon and click New Monitor → Heartbeat.
- Name it after your script:
Puppeteer — Dashboard ScraperorPuppeteer — Payment Flow Check. - Set Expected interval to match how often the script runs. For an hourly script, use 1 hour; for a daily check, use 24 hours.
- Set Grace period to allow for browser startup time and network latency. 15 minutes works for most scripts.
- Save and copy the Ping URL — it looks like
https://vigilmon.online/api/heartbeat/<unique-id>.
Step 2: Add a Heartbeat Ping to Your Puppeteer Script
Create a shared utility module:
// lib/vigilmon.js
const https = require("https");
async function pingVigilmon(url) {
if (!url) return;
return new Promise((resolve, reject) => {
const req = https.request(url, { method: "POST" }, (res) => {
resolve(res.statusCode);
});
req.on("error", reject);
req.setTimeout(10000, () => {
req.destroy(new Error("Vigilmon ping timed out"));
});
req.end();
});
}
module.exports = { pingVigilmon };
Wrap your Puppeteer script to send the heartbeat only after verified success:
// scripts/check-payment-flow.js
const puppeteer = require("puppeteer");
const { pingVigilmon } = require("../lib/vigilmon");
const HEARTBEAT_URL = process.env.VIGILMON_HEARTBEAT_URL;
async function run() {
const browser = await puppeteer.launch({
headless: "new",
args: ["--no-sandbox", "--disable-dev-shm-usage"],
});
try {
const page = await browser.newPage();
await page.goto("https://example.com/checkout", {
waitUntil: "networkidle2",
timeout: 30000,
});
// Verify critical elements are present
await page.waitForSelector("#checkout-form", { timeout: 10000 });
await page.waitForSelector("#payment-button", { timeout: 10000 });
// Optionally run through the flow
const title = await page.title();
if (!title.includes("Checkout")) {
throw new Error(`Unexpected page title: ${title}`);
}
console.log("Payment flow check passed");
// Only ping after all assertions pass
await pingVigilmon(HEARTBEAT_URL);
console.log("Vigilmon heartbeat sent");
} finally {
await browser.close();
}
}
run().catch((err) => {
console.error("Script failed:", err.message);
process.exit(1);
// No heartbeat sent — Vigilmon will alert after the grace period
});
The heartbeat fires only inside the try block after all assertions succeed. Errors in the catch/finally path suppress the ping, which triggers a Vigilmon alert after the grace period.
Step 3: Schedule the Script
Linux/macOS cron
# Edit crontab: crontab -e
# Run every 4 hours
0 */4 * * * VIGILMON_HEARTBEAT_URL="https://vigilmon.online/api/heartbeat/<id>" \
/usr/bin/node /home/user/scripts/check-payment-flow.js >> /var/log/puppeteer.log 2>&1
Systemd timer (recommended for Linux servers)
# /etc/systemd/system/puppeteer-check.service
[Unit]
Description=Puppeteer Payment Flow Check
[Service]
Type=oneshot
User=deploy
WorkingDirectory=/home/deploy/scripts
Environment=VIGILMON_HEARTBEAT_URL=https://vigilmon.online/api/heartbeat/<id>
ExecStart=/usr/bin/node check-payment-flow.js
StandardOutput=journal
StandardError=journal
# /etc/systemd/system/puppeteer-check.timer
[Unit]
Description=Run Puppeteer check every 4 hours
[Timer]
OnCalendar=*:0/4:00
Persistent=true
[Install]
WantedBy=timers.target
systemctl enable --now puppeteer-check.timer
GitHub Actions
# .github/workflows/puppeteer-check.yml
name: Puppeteer Health Check
on:
schedule:
- cron: "0 */4 * * *" # Every 4 hours
workflow_dispatch:
jobs:
puppeteer:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: "20"
- name: Install dependencies
run: npm ci
- name: Run Puppeteer script
env:
VIGILMON_HEARTBEAT_URL: ${{ secrets.VIGILMON_PUPPETEER_HEARTBEAT_URL }}
run: node scripts/check-payment-flow.js
Step 4: Handle Script Timeouts Explicitly
Puppeteer scripts can hang indefinitely on network waits or broken selectors. Add a top-level timeout to ensure the script always exits within a known window:
// Wrap with an overall timeout
const SCRIPT_TIMEOUT_MS = 5 * 60 * 1000; // 5 minutes
const timeoutHandle = setTimeout(() => {
console.error("Script timed out after 5 minutes — no heartbeat will be sent");
process.exit(1);
}, SCRIPT_TIMEOUT_MS);
run()
.then(() => {
clearTimeout(timeoutHandle);
process.exit(0);
})
.catch((err) => {
clearTimeout(timeoutHandle);
console.error("Script failed:", err.message);
process.exit(1);
});
Set Vigilmon's grace period to at least the script's maximum runtime plus buffer (e.g. 10 minutes grace for a 5-minute timeout).
Step 5: Monitor Multiple Scripts
For teams running several Puppeteer automation tasks, create one Vigilmon heartbeat monitor per script:
| Script | Purpose | Monitor name | Interval |
|---|---|---|---|
| check-payment-flow.js | Verifies checkout works | Puppeteer — Payment Flow | 4 h |
| scrape-dashboard.js | Updates analytics data | Puppeteer — Dashboard Scraper | 1 h |
| check-login.js | Verifies auth flow | Puppeteer — Login Check | 2 h |
| screenshot-homepage.js | Visual regression baseline | Puppeteer — Screenshot Capture | 24 h |
Store heartbeat URLs per-script in environment variables:
VIGILMON_PAYMENT_HEARTBEAT_URL="https://vigilmon.online/api/heartbeat/<id1>"
VIGILMON_DASHBOARD_HEARTBEAT_URL="https://vigilmon.online/api/heartbeat/<id2>"
VIGILMON_LOGIN_HEARTBEAT_URL="https://vigilmon.online/api/heartbeat/<id3>"
Step 6: Configure Alert Channels
In Vigilmon, go to Notifications → New Channel:
- Email — immediate alert when a heartbeat is missed
- Slack webhook — notify
#ops-alertsor#monitoringchannel
When a Puppeteer script stops pinging:
🔴 MISSED HEARTBEAT: Puppeteer — Payment Flow
Last ping: 5 hours ago
Expected interval: 4 hours
When it recovers:
✅ HEARTBEAT RECOVERED: Puppeteer — Payment Flow
Gap: 5 hours
What You're Now Catching
| Silent failure mode | How Vigilmon detects it | |---|---| | Cron job deleted or misconfigured | No ping → alert after grace period | | Chromium fails to launch (sandboxing, libs) | Process exits → no ping → alert | | Script hangs on a missing selector | Timeout fires → process exits → no ping → alert | | Assertion fails (wrong page content) | Error thrown → no ping → alert | | Node.js module fails to load | Process crashes → no ping → alert | | Network timeout swallows page load silently | Timeout throws → no ping → alert |
Puppeteer automates what humans would check manually — but only while it's running. Vigilmon's heartbeat monitors give you the external signal that Puppeteer can't provide: confirmation that your headless Chrome scripts ran and succeeded within the expected window.
Start monitoring your Puppeteer scripts today — register free at vigilmon.online.