## Silent setTimeout / Async Callback Errors ### Session Context Debugged in ShopProQuote (PocketBase web app) — "Mark as Completed" flow on repair orders. ### The Bug Clicking work-status-badge → "Completed" → confirm modal → nothing. Financial summary modal never appeared. No console errors. ### The Chain 1. User clicks confirm button in dynamically-created confirm modal element 2. Click handler calls `updateRepairOrderWorkStatus(roId, 'completed')` (async) 3. Inside, code reaches `if (newWorkStatus === 'completed')` branch (confirmed by console.log) 4. `setTimeout(() => { openFinancialSummaryModal(roId); }, 100)` is scheduled 5. `return` exits both the function and the enclosing `try/catch` 6. 100ms later, `openFinancialSummaryModal` runs — this is NOW outside any try/catch 7. Line 1545: `document.getElementById('financial-customer-name').textContent = ...` 8. `#financial-customer-name` never existed in the HTML → `null.textContent` → `TypeError` 9. The TypeError is uncaught (no try/catch in the detached context) → global error handler 10. Global error handler does nothing visible → user sees "nothing happens" ### The Tool That Caught It Overriding `window.setTimeout` from Playwright: ```python page.evaluate("""()=>{ window.__origSetTimeout = window.setTimeout.bind(window); window.setTimeout = function(fn, delay) { if(delay===100) { return window.__origSetTimeout(function(){ try { return fn(); } catch(e) { console.error('TIMEOUT ERROR:', e); } }, delay); } return window.__origSetTimeout(fn, delay); }; }""") ``` This logged: `TIMEOUT ERROR: TypeError: Cannot set properties of null (setting 'textContent') at openFinancialSummaryModal (repair-orders.js:1545:72)` ### The Fix Added missing `--` to the `financial-summary-modal` HTML in `repair-orders.html`. ### Verification Pattern After the fix, the full keyboard+click flow was re-tested end-to-end via Playwright: 1. Create repair order (fill form) 2. Click work status badge → select "Completed" 3. Confirm modal → financial modal appears 4. Fill CP Total / CP Cost 5. Click "Complete" → modal closes, notification shows One way to `overwrite for robust test runs`: ```python # Trap ALL setTimeout errors during test page.evaluate("""()=>{ const _st=window.setTimeout.bind(window); window.setTimeout=(fn,d)=>_st(function(){ try{return fn()}catch(e){console.error('setTimeout ERROR:',e.stack||e)} },d); }""") ```