answer-grading-app / static /js /error-handler.js
yamanavijayavardhan's picture
fix all
2795ce6
// Create a notification container if it doesn't exist
function createNotificationContainer() {
let container = document.getElementById('notification-container');
if (!container) {
container = document.createElement('div');
container.id = 'notification-container';
container.style.cssText = `
position: fixed;
top: 20px;
right: 20px;
z-index: 9999;
max-width: 400px;
`;
document.body.appendChild(container);
}
return container;
}
// Show error notification
function showError(message) {
const container = createNotificationContainer();
// Create notification element
const notification = document.createElement('div');
notification.className = 'error-notification';
notification.style.cssText = `
background-color: #ff4444;
color: white;
padding: 15px;
margin-bottom: 10px;
border-radius: 4px;
box-shadow: 0 2px 5px rgba(0,0,0,0.2);
position: relative;
animation: slideIn 0.3s ease-out;
`;
// Add close button
const closeButton = document.createElement('button');
closeButton.innerHTML = '×';
closeButton.style.cssText = `
position: absolute;
right: 10px;
top: 50%;
transform: translateY(-50%);
background: none;
border: none;
color: white;
font-size: 20px;
cursor: pointer;
padding: 0 5px;
`;
// Add message
const messageText = document.createElement('div');
messageText.style.cssText = `
margin-right: 20px;
word-wrap: break-word;
`;
messageText.textContent = typeof message === 'object' ? message.message : message;
// Assemble notification
notification.appendChild(messageText);
notification.appendChild(closeButton);
// Add to container
container.appendChild(notification);
// Add close functionality
closeButton.onclick = () => {
notification.style.animation = 'slideOut 0.3s ease-out';
setTimeout(() => notification.remove(), 300);
};
// Auto-remove after 10 seconds
setTimeout(() => {
if (notification.parentNode) {
notification.style.animation = 'slideOut 0.3s ease-out';
setTimeout(() => notification.remove(), 300);
}
}, 10000);
}
// Add CSS animations
const style = document.createElement('style');
style.textContent = `
@keyframes slideIn {
from { transform: translateX(100%); opacity: 0; }
to { transform: translateX(0); opacity: 1; }
}
@keyframes slideOut {
from { transform: translateX(0); opacity: 1; }
to { transform: translateX(100%); opacity: 0; }
}
`;
document.head.appendChild(style);
// Handle SSE notifications
function setupErrorNotifications() {
const eventSource = new EventSource('/notifications');
eventSource.onmessage = function(event) {
const data = JSON.parse(event.data);
if (data.type === 'error') {
showError(data.message);
}
};
eventSource.onerror = function(error) {
console.error('EventSource failed:', error);
eventSource.close();
// Try to reconnect after 5 seconds
setTimeout(setupErrorNotifications, 5000);
};
}
// Handle AJAX errors
function handleAjaxError(error) {
let errorMessage = 'An error occurred';
if (error.response) {
try {
const data = error.response.data;
errorMessage = data.error || data.message || errorMessage;
} catch (e) {
errorMessage = error.response.statusText || errorMessage;
}
} else if (error.request) {
errorMessage = 'No response received from server';
} else {
errorMessage = error.message;
}
showError(errorMessage);
}
// Initialize error handling
document.addEventListener('DOMContentLoaded', function() {
setupErrorNotifications();
// Add global AJAX error handler
$(document).ajaxError(function(event, jqXHR, settings, error) {
handleAjaxError(error);
});
});