Spaces:
Running
Running
File size: 4,245 Bytes
473668f |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 |
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();
})();
`;
|