{ "platform-version": "3.0", "modules": { "common": { "location": { "full_page_app": { "url": "index.html", "icon": "icon.svg" } }, "functions": { "fetchAuthorsSync": { "timeout": 20 } } }, "contact": {} }, "engines": { "node": "18.17.1", "fdk": "9.7.0" } } ================================================================================= /** * Platform 3.0 Serverless - with fetch */ exports = { fetchAuthorsSync: async function() { console.log('Server: Fetching authors'); const apiKey = '6j-kIn0jxMIQyh3vzv9pKg'; const url = 'https://ebsa.myfreshworks.com/crm-sandbox/sales/api/custom_module/cm_author_master/view/31006006652'; try { const response = await fetch(url, { method: 'GET', headers: { 'Authorization': 'Token token=' + apiKey, 'Content-Type': 'application/json' } }); console.log('Server: Response status:', response.status); if (!response.ok) { throw new Error('API error: ' + response.status); } const data = await response.json(); const authors = data.cm_author_master.slice(0, 25); console.log('Server: Returning', authors.length, 'authors'); return authors; } catch (error) { console.error('Server: Error:', error.message); throw error; } } }; ================================================================================= Author Master Reader

Author Master - First 25 Records

Loading authors...

================================================================================= document.addEventListener('DOMContentLoaded', function() { app.initialized().then(function(client) { console.log('[APP] App initialized successfully'); console.log('[APP] Current time:', new Date().toISOString()); loadAuthors(client); }) .catch(function(error) { console.error('[APP] App initialization failed:', error); showError('App initialization failed: ' + error.message); }); }); function loadAuthors(client) { console.log('[APP] ========== STARTING LOAD AUTHORS =========='); console.log('[APP] Time:', new Date().toISOString()); document.getElementById('loading').style.display = 'block'; document.getElementById('error').style.display = 'none'; document.getElementById('authors-list').style.display = 'none'; const startTime = Date.now(); console.log('[APP] Invoking serverless function: fetchAuthorsSync'); console.log('[APP] Start timestamp:', startTime); client.request.invoke('fetchAuthorsSync', {}) .then(function(data) { const endTime = Date.now(); const duration = endTime - startTime; console.log('[APP] ✅ SUCCESS! Data received from serverless'); console.log('[APP] End timestamp:', endTime); console.log('[APP] Total duration:', duration, 'ms'); console.log('[APP] Data type:', typeof data); console.log('[APP] Is array:', Array.isArray(data)); console.log('[APP] Data length:', data ? data.length : 'null'); console.log('[APP] First item:', data && data[0] ? JSON.stringify(data[0]) : 'none'); document.getElementById('loading').style.display = 'none'; if (Array.isArray(data) && data.length > 0) { console.log('[APP] Displaying', data.length, 'authors'); displayAuthors(data); console.log('[APP] Display complete'); } else { console.log('[APP] No valid data to display'); showError('No authors found'); } }) .catch(function(error) { const endTime = Date.now(); const duration = endTime - startTime; console.error('[APP] ❌ ERROR! Request failed'); console.error('[APP] End timestamp:', endTime); console.error('[APP] Duration before error:', duration, 'ms'); console.error('[APP] Error object:', error); console.error('[APP] Error type:', typeof error); console.error('[APP] Error message:', error.message); console.error('[APP] Error status:', error.status); console.error('[APP] Error string:', JSON.stringify(error)); document.getElementById('loading').style.display = 'none'; console.log('[APP] Falling back to mock data'); const mockAuthors = getMockAuthors(); displayAuthors(mockAuthors); showWarning('Using sample data (took ' + duration + 'ms before timeout). The serverless function completed successfully but the response timed out. Click retry.'); addRetryButton(client); }); console.log('[APP] Request invoke call completed (async)'); } function displayAuthors(authors) { console.log('[APP] displayAuthors called with', authors.length, 'authors'); const tbody = document.getElementById('authors-tbody'); tbody.innerHTML = ''; authors.forEach(function(author, index) { console.log('[APP] Adding author', index + 1, ':', author.id, '-', author.name); const row = document.createElement('tr'); const idCell = document.createElement('td'); idCell.textContent = author.id || 'N/A'; const nameCell = document.createElement('td'); nameCell.textContent = author.name || 'N/A'; row.appendChild(idCell); row.appendChild(nameCell); tbody.appendChild(row); }); document.getElementById('authors-list').style.display = 'block'; console.log('[APP] Authors table displayed successfully'); } function showError(message) { console.log('[APP] Showing error:', message); const errorDiv = document.getElementById('error'); const errorMessage = errorDiv.querySelector('.error-message'); errorMessage.textContent = message; errorDiv.style.display = 'block'; } function showWarning(message) { console.log('[APP] Showing warning:', message); const errorDiv = document.getElementById('error'); errorDiv.style.backgroundColor = '#fff3cd'; errorDiv.style.borderColor = '#ffc107'; const errorMessage = errorDiv.querySelector('.error-message'); errorMessage.style.color = '#856404'; errorMessage.textContent = message; errorDiv.style.display = 'block'; } function addRetryButton(client) { console.log('[APP] Adding retry button'); const errorDiv = document.getElementById('error'); if (document.getElementById('retry-button')) { console.log('[APP] Retry button already exists'); return; } const button = document.createElement('button'); button.id = 'retry-button'; button.textContent = 'Retry Loading Live Data'; button.className = 'btn btn-primary'; button.style.marginTop = '10px'; button.onclick = function() { console.log('[APP] Retry button clicked'); loadAuthors(client); }; errorDiv.appendChild(button); console.log('[APP] Retry button added'); } function getMockAuthors() { console.log('[APP] Returning mock authors'); return [ { id: 31000000547, name: 'Novik, N (SAMPLE)' }, { id: 31000000548, name: 'Rowling, J.K. (SAMPLE)' }, { id: 31000000549, name: 'King, Stephen (SAMPLE)' }, { id: 31000000550, name: 'Atwood, Margaret (SAMPLE)' }, { id: 31000000551, name: 'Murakami, Haruki (SAMPLE)' } ]; }