← back to Reidwitlin Landing
reidwitlin: contrarian FIX-THEN-SHIP — guard silent-zero-result feed failure (throw if <50 patterns), unify slug apostrophe-strip lib<->build, catch distinguishes integration vs feed errors; integration path exercised
d67eec93277af1275e2d2f7c8b8e72ef62cd3e31 · 2026-07-07 10:01:35 -0700 · Steve Abrams
Files touched
M lib/backfill-source-images.jsM scripts/backfill-source-images.jsM scripts/build-rwltd-data.js
Diff
commit d67eec93277af1275e2d2f7c8b8e72ef62cd3e31
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Tue Jul 7 10:01:35 2026 -0700
reidwitlin: contrarian FIX-THEN-SHIP — guard silent-zero-result feed failure (throw if <50 patterns), unify slug apostrophe-strip lib<->build, catch distinguishes integration vs feed errors; integration path exercised
---
lib/backfill-source-images.js | 6 +++++-
scripts/backfill-source-images.js | 3 +++
scripts/build-rwltd-data.js | 11 ++++++++++-
3 files changed, 18 insertions(+), 2 deletions(-)
diff --git a/lib/backfill-source-images.js b/lib/backfill-source-images.js
index 6259860..1756b57 100644
--- a/lib/backfill-source-images.js
+++ b/lib/backfill-source-images.js
@@ -15,7 +15,11 @@
*/
const https = require('https');
-const slug = s => String(s || '').toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/(^-|-$)/g, '');
+// MUST match build-rwltd-data.js's slug: drop apostrophes BEFORE the char-class
+// collapse so "I'm Crushed" -> "im-crushed" (matching the vendor mfr_sku), not
+// "i-m-crushed". A divergence here silently breaks the feed-key<->sku lookup for
+// any apostrophe-titled pattern. (Contrarian catch, 2026-07-07.)
+const slug = s => String(s || '').toLowerCase().replace(/['’`]/g, '').replace(/[^a-z0-9]+/g, '-').replace(/(^-|-$)/g, '');
function get(url) {
// Shopify serves an empty body to the default node UA — send a browser UA.
diff --git a/scripts/backfill-source-images.js b/scripts/backfill-source-images.js
index 0a91f24..8844ce7 100644
--- a/scripts/backfill-source-images.js
+++ b/scripts/backfill-source-images.js
@@ -21,6 +21,9 @@ const BUCKET_ORDER = ['white','grey','black','pink','red','orange','brown','gold
// Apply to both arrays (a drafted colorway getting a photo must be able to restore).
const r1 = await backfillFromSourceFeed(snap.products);
+ // Feed-sanity guard: a bot-block/empty 200 returns ~0 patterns. Bail BEFORE the
+ // re-partition rather than silently re-draft (Contrarian catch, 2026-07-07).
+ if (r1.sourcePatterns < 50) { console.error(`ABORT: source feed suspicious (${r1.sourcePatterns} patterns) — not repartitioning`); process.exit(1); }
const r2 = await backfillFromSourceFeed(snap.drafts);
const backfilled = r1.backfilled + r2.backfilled;
const conflicts = [...r1.conflicts, ...r2.conflicts];
diff --git a/scripts/build-rwltd-data.js b/scripts/build-rwltd-data.js
index 6d9dd2f..40bf589 100644
--- a/scripts/build-rwltd-data.js
+++ b/scripts/build-rwltd-data.js
@@ -340,10 +340,19 @@ async function main() {
try {
const { backfillFromSourceFeed } = require('../lib/backfill-source-images');
const bf = await backfillFromSourceFeed(products);
+ // Guard the SILENT failure mode: a bot-block / rate-limit / empty CDN response
+ // returns HTTP 200 with 0 products (no throw) — which would quietly re-draft
+ // ~190 colorways. The real feed has hundreds of patterns; <50 means the feed
+ // lied. Throw so the catch logs a LOUD skip instead of silently gutting the
+ // catalog. (Contrarian catch, 2026-07-07.)
+ if (bf.sourcePatterns < 50) throw new Error(`source feed suspicious: only ${bf.sourcePatterns} patterns returned (bot-block/empty?) — refusing to silently skip backfill`);
console.log(` source-image backfill: ${bf.backfilled} colorways got an authoritative photo (feed ${bf.sourcePatterns} patterns / ${bf.indexSize} keys)`);
if (bf.conflicts.length) console.log(` ${bf.conflicts.length} already-imaged differ from source (kept ours): ${bf.conflicts.map(c => c.handle.split('--')[0]).join(', ')}`);
} catch (e) {
- console.log(` source-image backfill SKIPPED (feed unreachable: ${e.message}) — no-photo colorways stay drafted`);
+ // Distinguish a real feed problem from a wiring/integration bug — the catch
+ // must not relabel a code error as a network blip (Contrarian Hole 3).
+ const kind = /suspicious|ENOTFOUND|ETIMEDOUT|ECONNRESET|socket|getaddrinfo|JSON/i.test(e.message) ? 'feed problem' : 'INTEGRATION ERROR';
+ console.log(` source-image backfill SKIPPED (${kind}: ${e.message}) — no-photo colorways stay drafted`);
}
// HARD RULE (Steve, 2026-07-07): all SKUs must have their OWN photo or go to DRAFT.
← e798590 reidwitlin: wire source-image backfill into canonical build
·
back to Reidwitlin Landing
·
auto-save: 2026-07-07T12:30:21 (4 files) — lib/backfill-sour b8b384a →