/** * Auth utilities - safe JSON parsing and error display * Following the pattern from static/js/watchlist.js (global exports) */ // API base URL - use relative path for same-origin const API_BASE = '/api'; /** * Safely parse JSON string with fallback * @param {string} text - The JSON string to parse * @param {*} fallback - The fallback value if parsing fails (default: null) * @returns {*} Parsed object or fallback value */ function safeJsonParse(text, fallback = null) { try { if (text === undefined || text === null || text === '') { return fallback; } return JSON.parse(text); } catch (error) { console.error('JSON parse error:', error.message); return fallback; } } /** * Display error message in the specified element * Handles string, object, and array errors properly * @param {string} elementId - The ID of the element to display error in * @param {*} error - The error (string, object, or array) * @param {string} defaultMessage - Default message if error is invalid */ function displayError(elementId, error, defaultMessage = 'Une erreur est survenue') { const errorDiv = document.getElementById(elementId); if (!errorDiv) { console.error('Error element not found:', elementId); return; } let message = defaultMessage; if (error === null || error === undefined) { message = defaultMessage; } else if (typeof error === 'string') { message = error; } else if (typeof error === 'object') { // Handle array errors if (Array.isArray(error)) { message = error.join('\n'); } // Handle FastAPI HTTPException detail (can be string or object) else if (error.detail) { if (typeof error.detail === 'string') { message = error.detail; } else if (typeof error.detail === 'object' && error.detail.msg) { message = error.detail.msg; } else { // Stringify the object to avoid "[object Object]" message = JSON.stringify(error.detail); } } // Handle generic object else { message = JSON.stringify(error); } } errorDiv.textContent = message; errorDiv.classList.remove('hidden'); // Hide success message if visible const successDiv = document.getElementById(elementId.replace('Error', 'Success')); if (successDiv) { successDiv.classList.add('hidden'); } } /** * Display success message in the specified element * @param {string} elementId - The ID of the element to display success in * @param {string} message - The success message */ function displaySuccess(elementId, message) { const successDiv = document.getElementById(elementId); if (!successDiv) { console.error('Success element not found:', elementId); return; } successDiv.textContent = message; successDiv.classList.remove('hidden'); // Hide error message if visible const errorDiv = document.getElementById(elementId.replace('Success', 'Error')); if (errorDiv) { errorDiv.classList.add('hidden'); } } // Export globally (following watchlist.js pattern) window.safeJsonParse = safeJsonParse; window.displayError = displayError; window.displaySuccess = displaySuccess; window.API_BASE = API_BASE;