Spaces:
Running
Running
export const ERROR_DETECTOR_ID = "deepsite-error-detector"; | |
export const errorDetectorScript = ` | |
(function() { | |
const errors = []; | |
let errorTimeout = null; | |
const MAX_ERRORS = 10; | |
const BATCH_DELAY = 1000; // Wait 1 second before sending errors | |
// Create a safe error object that can be serialized | |
function createSafeError(error, type, context = {}) { | |
return { | |
type, | |
message: error?.message || String(error), | |
stack: error?.stack, | |
lineNumber: error?.lineNumber || context.lineNumber, | |
columnNumber: error?.columnNumber || context.columnNumber, | |
fileName: error?.fileName || context.fileName, | |
timestamp: new Date().toISOString(), | |
...context | |
}; | |
} | |
// Send errors to parent window (always send, even if empty) | |
function sendErrors() { | |
window.parent.postMessage({ | |
type: 'PREVIEW_ERRORS', | |
errors: errors.slice(0, MAX_ERRORS), // Limit errors sent | |
url: window.location.href | |
}, '*'); | |
errors.length = 0; // Clear sent errors | |
} | |
// Batch errors to avoid spamming | |
function queueError(error) { | |
errors.push(error); | |
if (errorTimeout) clearTimeout(errorTimeout); | |
errorTimeout = setTimeout(sendErrors, BATCH_DELAY); | |
} | |
// Global error handler | |
window.addEventListener('error', function(event) { | |
const error = createSafeError(event.error || event.message, 'runtime-error', { | |
lineNumber: event.lineno, | |
columnNumber: event.colno, | |
fileName: event.filename, | |
errorType: 'JavaScript Error' | |
}); | |
queueError(error); | |
}); | |
// Unhandled promise rejection handler | |
window.addEventListener('unhandledrejection', function(event) { | |
const error = createSafeError(event.reason, 'unhandled-promise', { | |
promise: event.promise, | |
errorType: 'Unhandled Promise Rejection' | |
}); | |
queueError(error); | |
}); | |
// Override console.error to catch logged errors | |
const originalConsoleError = console.error; | |
console.error = function(...args) { | |
originalConsoleError.apply(console, args); | |
const error = createSafeError(args.join(' '), 'console-error', { | |
errorType: 'Console Error', | |
args: args.map(arg => String(arg)) | |
}); | |
queueError(error); | |
}; | |
// Monitor failed resource loads (404s, etc) | |
window.addEventListener('error', function(event) { | |
if (event.target !== window) { | |
// This is a resource loading error | |
const target = event.target; | |
const error = createSafeError(\`Failed to load resource: \${target.src || target.href}\`, 'resource-error', { | |
tagName: target.tagName, | |
src: target.src || target.href, | |
errorType: 'Resource Loading Error' | |
}); | |
queueError(error); | |
} | |
}, true); // Use capture phase to catch resource errors | |
// Monitor for common React errors | |
if (window.React && window.React.version) { | |
const originalError = console.error; | |
console.error = function(...args) { | |
originalError.apply(console, args); | |
const errorString = args.join(' '); | |
if (errorString.includes('ReactDOM.render is no longer supported') || | |
errorString.includes('Cannot read property') || | |
errorString.includes('Cannot access property')) { | |
const error = createSafeError(errorString, 'react-error', { | |
errorType: 'React Error', | |
reactVersion: window.React.version | |
}); | |
queueError(error); | |
} | |
}; | |
} | |
// Report current state of errors | |
function reportCurrentState() { | |
sendErrors(); | |
} | |
// Send initial ready message and current error state | |
window.addEventListener('load', reportCurrentState); | |
// Monitor for DOM changes that might clear errors | |
const observer = new MutationObserver(() => { | |
// Small delay to let any new errors register | |
setTimeout(reportCurrentState, 100); | |
}); | |
// Start observing once DOM is ready | |
if (document.body) { | |
observer.observe(document.body, { | |
subtree: true, | |
childList: true | |
}); | |
} else { | |
window.addEventListener('DOMContentLoaded', () => { | |
observer.observe(document.body, { | |
subtree: true, | |
childList: true | |
}); | |
}); | |
} | |
// Send initial state | |
reportCurrentState(); | |
})(); | |
`; | |