43 lines
1.4 KiB
Markdown
43 lines
1.4 KiB
Markdown
# Silent Cascade Failure — JS TypeError Kills Async Operations
|
|
|
|
## Pattern (discovered Jul 12, 2026)
|
|
|
|
A single `TypeError` (e.g. `.classList.add()` on a `null` element) in early synchronous inline script kills ALL subsequent code — including `fetch()` calls that would load nav, content, or UI elements.
|
|
|
|
The symptom surface is confusing: blank page, no menu, no content, no visible error.
|
|
|
|
## Example
|
|
|
|
```javascript
|
|
// WRONG — crashes before nav fetch runs
|
|
if (Ops.isAuthenticated()) {
|
|
overlay.classList.remove('show');
|
|
document.getElementById('logoutBtn').classList.add('show'); // TypeError if nav not loaded
|
|
loadContent(); // Never runs
|
|
}
|
|
fetch('/nav.html').then(...) // Never runs either
|
|
```
|
|
|
|
## Fix pattern
|
|
|
|
Always guard DOM lookups that depend on async-loaded content:
|
|
|
|
```javascript
|
|
// Wait for async content before accessing
|
|
var wait = setInterval(function() {
|
|
var el = document.getElementById('logoutBtn');
|
|
if (el) {
|
|
el.classList.add('show');
|
|
clearInterval(wait);
|
|
loadContent();
|
|
}
|
|
}, 100);
|
|
```
|
|
|
|
## Prevention checklist
|
|
|
|
- [ ] Every `getElementById()` call is guarded (especially elements from fetched templates)
|
|
- [ ] Auth logic does NOT touch DOM elements from separate fetches
|
|
- [ ] `fetch()` / `setInterval()` are NOT placed after unguarded DOM access
|
|
- [ ] Inline scripts tolerate missing elements without crashing
|