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();
})();
`;