// Error handling for HTMX requests // Shows toast notifications for failed requests and preserves user input // Show error toast with a message function showErrorToast(message) { const toastBody = document.getElementById('errorToastBody'); const toastEl = document.getElementById('errorToast'); if (!toastBody || !toastEl) { console.error('Error toast elements not found'); alert(message); // Fallback to alert return; } toastBody.textContent = message; const toast = new bootstrap.Toast(toastEl, { delay: 8000 }); toast.show(); } // Handle HTMX response errors - this fires BEFORE swap document.body.addEventListener('htmx:beforeSwap', function(evt) { const xhr = evt.detail.xhr; const status = xhr.status; // Handle 403 Forbidden (CSRF errors) if (status === 403) { // Check if it's a CSRF error by looking at response const responseText = xhr.responseText || ''; if (responseText.includes('CSRF') || responseText.includes('csrf')) { // Prevent the swap so user input is preserved evt.detail.shouldSwap = false; evt.detail.isError = false; // Prevent htmx:responseError from firing showErrorToast('Your session has expired. Please refresh the page to continue.'); return; } // Other 403 errors evt.detail.shouldSwap = false; showErrorToast('Access denied. Please refresh the page and try again.'); return; } // Handle 5xx server errors if (status >= 500) { evt.detail.shouldSwap = false; showErrorToast('Server error. Please try again later.'); return; } // Handle network errors (status 0) if (status === 0) { evt.detail.shouldSwap = false; showErrorToast('Network error. Please check your connection and try again.'); return; } // For 4xx errors (except 403), allow the swap as the server may return helpful error HTML // but show a toast as backup if (status >= 400 && status < 500) { // Allow swap but also show toast showErrorToast('Request failed. Please check your input and try again.'); } }); // Fallback handler for any errors that slip through document.body.addEventListener('htmx:responseError', function(evt) { console.error('HTMX Response Error:', evt.detail); // Toast already shown by beforeSwap handler in most cases }); // Handle send errors (network failures before response) document.body.addEventListener('htmx:sendError', function(evt) { showErrorToast('Failed to send request. Please check your connection.'); });