Add 10-second error suppression grace period after SPA navigation

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
root
2025-12-27 22:01:36 +00:00
parent f08d3de0c8
commit c1485ccbdb
3 changed files with 42 additions and 0 deletions

View File

@@ -50,6 +50,14 @@ class Ajax {
const error = event.reason; const error = event.reason;
console.error('Uncaught Ajax error:', error); console.error('Uncaught Ajax error:', error);
// Suppress errors during navigation grace period
// After page navigation, pending requests from the old page may error out
// These errors are not relevant to the new page
if (typeof Spa !== 'undefined' && Spa.is_within_navigation_grace_period()) {
console.log('[Ajax] Suppressing error modal during navigation grace period');
return;
}
// Show error modal for uncaught Ajax errors // Show error modal for uncaught Ajax errors
// In debug mode, use fatal_error() for detailed file/line info // In debug mode, use fatal_error() for detailed file/line info
if (typeof Modal !== 'undefined') { if (typeof Modal !== 'undefined') {

View File

@@ -160,6 +160,14 @@ class Exception_Handler {
return; return;
} }
// Suppress errors during navigation grace period
// After page navigation, pending requests from the old page may error out
// These errors are not relevant to the new page
if (typeof Spa !== 'undefined' && Spa.is_within_navigation_grace_period()) {
console.log('[Exception_Handler] Suppressing error flash during navigation grace period');
return;
}
// Extract message from Error object or string // Extract message from Error object or string
let error_text; let error_text;
if (exception instanceof Error) { if (exception instanceof Error) {

View File

@@ -43,6 +43,28 @@ class Spa {
// Flag to track if initial load is complete (for session validation) // Flag to track if initial load is complete (for session validation)
static _initial_load_complete = false; static _initial_load_complete = false;
// Timestamp of last navigation start - used for error suppression grace period
static _navigation_timestamp = 0;
// Grace period in milliseconds for suppressing errors after navigation
static NAVIGATION_GRACE_PERIOD_MS = 10000;
/**
* Check if we're within the navigation grace period
*
* During the 10 seconds after navigation starts, pending AJAX requests from the
* previous page may error out (because their context is gone). These errors should
* not be shown to the user as they're not relevant to the new page.
*
* @returns {boolean} True if within grace period, false otherwise
*/
static is_within_navigation_grace_period() {
if (Spa._navigation_timestamp === 0) {
return false;
}
return (Date.now() - Spa._navigation_timestamp) < Spa.NAVIGATION_GRACE_PERIOD_MS;
}
/** /**
* Disable SPA navigation - all navigation becomes full page loads * Disable SPA navigation - all navigation becomes full page loads
* Call this when errors occur or forms are dirty * Call this when errors occur or forms are dirty
@@ -521,6 +543,10 @@ class Spa {
Spa.is_dispatching = true; Spa.is_dispatching = true;
// Record navigation timestamp for error suppression grace period
// Errors from previous page's pending requests should be ignored for 10 seconds
Spa._navigation_timestamp = Date.now();
try { try {
const opts = { const opts = {
history: options.history || 'auto', history: options.history || 'auto',