Skip to content

Commit f5e0461

Browse files
arnobt78cursoragent
andcommitted
fix(sentry): auto-reload on ChunkLoadError; order form warn not error (REQ-0014/0015)
REQ-0014: ErrorBoundary.componentDidCatch detects ChunkLoadError by name/message and calls window.location.reload() once (sessionStorage loop guard) instead of reporting to Sentry. Fixes post-deploy stale-chunk Sentry noise for demo users. REQ-0015: OrderDialog RHF invalid-submit callback changed from logger.error to logger.warn. Client-side form validation failures are expected UX, not server errors — logger.error routes to Sentry, logger.warn does not. Automated: lint ✓ test 284 ✓ invalidate 200 ✓ build ✓ Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent 129c359 commit f5e0461

7 files changed

Lines changed: 84 additions & 14 deletions

File tree

.agile-v/DECISION_LOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,6 @@ Format: `TIMESTAMP | AGENT | DECISION | RATIONALE | REQ-ID`
2020
2026-05-19T00:00:00Z | build-agent | Export error HTTP helpers from lib/api | Single import path for hooks and logger consumers | REQ-0012
2121
2026-05-19T00:00:00Z | build-agent | Track SENTRY audit in docs/ | Historical cases + status header; agile-v pointers | REQ-0009
2222
2026-05-19T00:00:00Z | build-agent | Remaining API Zod safeParse sweep | Payment/shipping/notifications/auth/AI; logger.warn everywhere | REQ-0013
23+
2026-06-27T00:00:00Z | build-agent | ChunkLoadError auto-reload in ErrorBoundary | Stale Vercel chunk after deploy; reload once with sessionStorage loop guard; skip Sentry | REQ-0014
24+
2026-06-27T00:00:00Z | build-agent | OrderDialog logger.error → logger.warn for RHF invalid callback | Client-side form validation is expected UX path, not a server error; logger.error routes to Sentry | REQ-0015
25+
2026-06-27T00:00:00Z | red-team | Hydration on /admin/dashboard-overall-insights MONITOR only | Single demo user (test@admin.com) Asia/Karachi tz; no date component change warranted yet | REQ-0009

.agile-v/REQUIREMENTS.md

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,48 @@ Canonical REQ source. All artifacts link via `REQ-XXXX`. Status: `done` | `verif
214214

215215
---
216216

217+
## REQ-0014 — ChunkLoadError auto-reload in ErrorBoundary
218+
219+
| Field | Value |
220+
|-------|-------|
221+
| **Priority** | P1 |
222+
| **Risk** | R2 |
223+
| **Status** | done |
224+
225+
**Intent:** After a Vercel deploy, users with stale tab/page receive `ChunkLoadError` when a lazy import tries to fetch a now-invalidated chunk hash. Currently `ErrorBoundary.componentDidCatch` logs and reports to Sentry and shows a crash UI. The correct fix is to silently auto-reload on `ChunkLoadError`, restoring the user to the fresh deploy without a Sentry event.
226+
227+
**Acceptance criteria**
228+
229+
- AC1: `ErrorBoundary.componentDidCatch` detects `ChunkLoadError` by name and triggers `window.location.reload()` — no Sentry capture, no crash UI shown
230+
- AC2: Non-`ChunkLoadError` errors continue to report to Sentry and show fallback UI unchanged
231+
- AC3: A `sessionStorage` guard prevents an infinite reload loop (reload once, then fall through to crash UI)
232+
- AC4: `ErrorBoundary.tsx` updated; `app/layout.tsx` unchanged
233+
234+
**Artifacts:** `components/shared/ErrorBoundary.tsx`
235+
236+
---
237+
238+
## REQ-0015 — OrderDialog RHF validation logger level
239+
240+
| Field | Value |
241+
|-------|-------|
242+
| **Priority** | P1 |
243+
| **Risk** | R1 |
244+
| **Status** | done |
245+
246+
**Intent:** `OrderDialog.tsx:949` calls `logger.error("Order form validation errors:", errors)` in the RHF `handleSubmit` invalid callback. This fires for pure client-side form validation failures (missing fields, wrong type) — it never reaches any API. `logger.error` routes through Sentry; `logger.warn` does not. Client-side form validation is expected UX feedback, not a production error.
247+
248+
**Acceptance criteria**
249+
250+
- AC1: `logger.error` at line ~949 changed to `logger.warn`
251+
- AC2: `console.error` at line ~945 changed to `console.warn` (debug noise reduction)
252+
- AC3: API-level errors at lines ~487 and ~628 (`logger.error("Order creation error:", ...)`, `logger.error("Order update error:", ...)`) remain as `logger.error` (those are genuine server failures)
253+
- AC4: No other logic changed in `OrderDialog.tsx`
254+
255+
**Artifacts:** `components/orders/OrderDialog.tsx`
256+
257+
---
258+
217259
## REQ-0013 — Remaining API Zod consistency
218260

219261
| Field | Value |

.agile-v/STATE.md

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,21 @@
33
| Field | Value |
44
|-------|-------|
55
| **Cycle** | C1 |
6-
| **Phase** | `phases/01-sentry-groq-select` |
7-
| **Infinity Loop stage** | VerifyEvolve (Human Gate 2 pending) |
8-
| **Last updated** | 2026-05-19 |
9-
| **Active REQ range** | REQ-0001 … REQ-0013 |
10-
| **Prod deploy target** | `9a2e37c` (REQ-0013); docs HEAD `c0e15b3` |
6+
| **Phase** | `phases/02-sentry-chunk-order-fix` |
7+
| **Infinity Loop stage** | ProveVerify (REQ-0014/0015 code done, lint+test PASS, awaiting deploy) |
8+
| **Last updated** | 2026-06-27 |
9+
| **Active REQ range** | REQ-0001 … REQ-0015 |
10+
| **Prod deploy target** | pending push (REQ-0014/0015); baseline `9a2e37c` |
1111
| **Human Gate 1** | APPROVED (retroactive bootstrap) |
12-
| **Human Gate 2** | PENDING — Sentry 24h + manual nav smoke |
12+
| **Human Gate 2** | PENDING — Sentry 24h + manual nav smoke; new REQ-0014/0015 pending automated pass |
1313
| **Resume token** ||
1414

1515
## Current focus
1616

17-
1. **REQ-0009** — 24h Sentry regression after prod deploy (`docs/SENTRY_ERRORS.md`)
18-
2. **REQ-0001/0006** — manual removeChild nav smoke (optional)
19-
3. **C2** — new work only via new REQ-XXXX + Infinity Loop
17+
1. **REQ-0014** — ChunkLoadError auto-reload in `ErrorBoundary` (stale deploy chunk)
18+
2. **REQ-0015**`OrderDialog` `logger.error``logger.warn` for RHF client-side validation callback
19+
3. **REQ-0009** — Sentry regression watch: hydration on `/admin/dashboard-overall-insights` MONITOR only
20+
4. **REQ-0001/0006** — manual removeChild nav smoke (optional)
2021

2122
## Session resume (every chat)
2223

.agile-v/VALIDATION_SUMMARY.md

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
# Validation Summary — Cycle C1
22

3-
**Generated:** 2026-05-28
3+
**Generated:** 2026-06-27
44
**eval_gate_status:** PENDING (Human Gate 2)
5-
**Red Team:** automated pass; manual prod QA partial
5+
**Red Team:** automated pass; manual prod QA partial; REQ-0014/0015 lint+test PASS
66

77
---
88

@@ -38,6 +38,9 @@
3838
| VS-004 | INFO | Products POST/PUT Zod + 4xx logger guard | PASS (automated) |
3939
| VS-005 | INFO | Catalog CRUD Zod + API barrel exports | PASS (automated) |
4040
| VS-006 | INFO | Remaining API Zod sweep (payment/shipping/auth/AI) | PASS (automated) |
41+
| VS-007 | INFO | ChunkLoadError auto-reload in ErrorBoundary | PASS (lint + 284 tests) |
42+
| VS-008 | INFO | OrderDialog RHF validation logger level | PASS (lint + 284 tests) |
43+
| VS-009 | INFO | Hydration /admin/dashboard-overall-insights | MONITOR (single demo user) |
4144

4245
---
4346

@@ -48,6 +51,8 @@
4851
- [ ] Bell dropdown QA (post-deploy)
4952
- [ ] Dialog nav smoke (OrderDialog)
5053
- [ ] Sentry 24h review (`.agile-v/REVALIDATION_LOG.md`)
54+
- [ ] lint + test + build pass for REQ-0014/0015
55+
- [ ] Deploy REQ-0014/0015 and confirm no new ChunkLoadError / Order validation Sentry events
5156

5257
**Approver:** _pending_
5358
**Date:** _pending_

LICENSE

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
MIT License
22

3+
SPDX-License-Identifier: MIT
4+
35
Copyright (c) 2026 Arnob Mahmud
46

57
Permission is hereby granted, free of charge, to any person obtaining a copy

components/orders/OrderDialog.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -941,12 +941,12 @@ export default function OrderDialog({
941941
onSubmit={createFormMethods.handleSubmit(
942942
handleCreateOrder,
943943
(errors) => {
944-
// Log validation errors to console for debugging
945-
console.error(
944+
// Client-side RHF validation failure — expected UX path, not a server error
945+
console.warn(
946946
"Form validation errors:",
947947
JSON.stringify(errors, null, 2),
948948
);
949-
logger.error("Order form validation errors:", errors);
949+
logger.warn("Order form validation errors:", errors);
950950

951951
// Helper function to extract error messages from nested objects
952952
const extractErrorMessages = (

components/shared/ErrorBoundary.tsx

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,23 @@ export class ErrorBoundary extends Component<Props, State> {
3939
}
4040

4141
public componentDidCatch(error: Error, errorInfo: ErrorInfo) {
42+
// ChunkLoadError fires when a Vercel deploy invalidates a cached JS chunk that the
43+
// user's stale tab still references. Silently reload once to pick up the new build.
44+
// A sessionStorage guard prevents an infinite reload loop if the chunk is genuinely missing.
45+
if (
46+
error.name === "ChunkLoadError" ||
47+
error.message?.includes("Failed to load chunk")
48+
) {
49+
const key = "chunk_reload_attempted";
50+
if (!sessionStorage.getItem(key)) {
51+
sessionStorage.setItem(key, "1");
52+
window.location.reload();
53+
return;
54+
}
55+
// Already tried once — fall through to normal error handling below
56+
sessionStorage.removeItem(key);
57+
}
58+
4259
logger.error("ErrorBoundary caught an error:", {
4360
error: error.message,
4461
stack: error.stack,

0 commit comments

Comments
 (0)