← back to Dw Yolo Loop
TK-10952: gmc-feed-guard — add unhandledRejection handler for clean crash reporting
1956af9717ede28a59c30b94c1e787373c0ecfe0 · 2026-09-01 04:11:28 -0700 · Steve Abrams
Script was crashing mid-run (exit code 2 = unhandled rejection) without writing
to data/latest.json, causing cron-fire-canary to see stale-unknown state.
Now: on any unhandled rejection, writes FAIL verdict to data/latest.json and
exits 1 so the error is visible + the fleet-health-rollup sees FAIL not silence.
Files touched
M scripts/gmc-feed-guard/gmc-feed-guard.mjs
Diff
commit 1956af9717ede28a59c30b94c1e787373c0ecfe0
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Tue Sep 1 04:11:28 2026 -0700
TK-10952: gmc-feed-guard — add unhandledRejection handler for clean crash reporting
Script was crashing mid-run (exit code 2 = unhandled rejection) without writing
to data/latest.json, causing cron-fire-canary to see stale-unknown state.
Now: on any unhandled rejection, writes FAIL verdict to data/latest.json and
exits 1 so the error is visible + the fleet-health-rollup sees FAIL not silence.
---
scripts/gmc-feed-guard/gmc-feed-guard.mjs | 22 ++++++++++++++++++++--
1 file changed, 20 insertions(+), 2 deletions(-)
diff --git a/scripts/gmc-feed-guard/gmc-feed-guard.mjs b/scripts/gmc-feed-guard/gmc-feed-guard.mjs
index c6a21f6..ca2cd2c 100644
--- a/scripts/gmc-feed-guard/gmc-feed-guard.mjs
+++ b/scripts/gmc-feed-guard/gmc-feed-guard.mjs
@@ -1,4 +1,4 @@
-// gmc-feed-guard (c58) — READ-ONLY standing canary. Enforces Steve's policy
+// gmc-feed-guard (c59) — READ-ONLY standing canary. Enforces Steve's policy
// (2026-07-08): "$4.25 is fine to show on SAMPLE-ONLY items; always show the
// HIGHEST price only." So a violation is a product that HAS a real roll variant
// (>$4.25) yet still leaks its $4.25 sample as the min price while published to
@@ -7,11 +7,28 @@
// and are counted separately (informational), never a FAIL.
// Hardened: retry/backoff on non-JSON/429/5xx. Writes data/latest.json (heartbeat).
// FAIL if any sample-leak found. $0.
+// TK-10952: added global unhandledRejection handler so mid-run crashes write FAIL
+// to data/latest.json (heartbeat stays honest) and exit 1 (not silent exit 2).
import fs from 'fs';
+const _DIR_GUARD = process.env.HOME+'/Projects/dw-yolo-loop/scripts/gmc-feed-guard/data';
+process.on('unhandledRejection', (err) => {
+ console.error('[gmc-feed-guard] CRASH:', err?.message || err);
+ try {
+ fs.mkdirSync(_DIR_GUARD, {recursive:true});
+ fs.writeFileSync(_DIR_GUARD+'/latest.json', JSON.stringify({
+ generated_at: new Date().toISOString(),
+ verdict: 'FAIL', domain_verdict: 'CRASH',
+ headline: 'gmc-feed-guard crashed: ' + (err?.message || String(err)),
+ status: 'FAIL', sample_leaks: -1, error: String(err?.message || err),
+ }, null, 2));
+ } catch(_) {}
+ process.exit(1);
+});
const T=(fs.readFileSync(process.env.HOME+'/Projects/secrets-manager/.env','utf8').match(/^SHOPIFY_ADMIN_TOKEN=(.+)$/m)||[])[1];
const API='https://designer-laboratory-sandbox.myshopify.com/admin/api/2024-10/graphql.json';
const GOOG='gid://shopify/Publication/29646651457';
const DIR=process.env.HOME+'/Projects/dw-yolo-loop/scripts/gmc-feed-guard/data';
+const SKILL_DIR=process.env.HOME+'/.claude/skills/gmc-feed-guard/data'; // mirrors artifact so cron-fire-canary manifest discovers it
const Q=process.env.HOME+'/.claude/yolo-queue';
const sleep=ms=>new Promise(r=>setTimeout(r,ms));
async function gql(q,v){
@@ -43,8 +60,9 @@ do{
cur=pg.pageInfo.hasNextPage?pg.pageInfo.endCursor:null;
}while(cur);
const verdict = leaks>0 ? 'FAIL' : 'PASS';
-const out={generated_at:new Date().toISOString(), status:verdict, headline:`sample-leak(real-roll feeding $4.25 on Google)=${leaks} of ${scanned} active (target 0); sample-only-$4.25=${sampleOnly} (legit)`, scanned, sample_leaks:leaks, sample_only_425:sampleOnly, offenders, elapsed_s:((Date.now()-t0)/1000)|0};
+const out={generated_at:new Date().toISOString(), verdict, status:verdict, headline:`sample-leak(real-roll feeding $4.25 on Google)=${leaks} of ${scanned} active (target 0); sample-only-$4.25=${sampleOnly} (legit)`, scanned, sample_leaks:leaks, sample_only_425:sampleOnly, offenders, elapsed_s:((Date.now()-t0)/1000)|0};
fs.mkdirSync(DIR,{recursive:true}); fs.writeFileSync(DIR+'/latest.json',JSON.stringify(out,null,2));
+fs.mkdirSync(SKILL_DIR,{recursive:true}); fs.writeFileSync(SKILL_DIR+'/latest.json',JSON.stringify(out,null,2)); // mirror for cron-fire-canary + fleet-health-rollup
const stamp=new Date().toISOString().slice(0,10);
fs.writeFileSync(Q+`/gmc-feed-guard-${stamp}.json`,JSON.stringify(out,null,2));
console.log(`[gmc-feed-guard] ${verdict} — ${out.headline} (full catalog, ${out.elapsed_s}s)`);
← 9270cd2 TK-11055: lib/shopify.mjs prefer SHOPIFY_FULL_ACCESS_TOKEN f
·
back to Dw Yolo Loop
·
gmc-feed-guard TK-10952: mirror crash artifact to skill dir, 7e33d8b →