1/** 2 * Global handler for unhandled promise rejections 3 * Ensures that all rejections are Error objects before propagating to Sentry 4 * Fixes: "Non-Error promise rejection captured with value: overlay" 5 */ 6 7// CRITICAL: Define global function stubs IMMEDIATELY to prevent ReferenceErrors 8// These must be defined BEFORE any other code runs (including the IIFE below) 9(function() { 10 'use strict'; 11 var noop = function() {}; 12 var globalFunctions = ['calculateWidth', 'becomeFan', 'sortIsotope', 'arrParsedGenres', 'l18nSearchMoreResults', 'Hogan', 'cast', 'LIDNotify', 'LIDNotifyId', 'codemirrKeydownEvent', 'codemirrorSuggest', 13 'importRemote', 'importSoundCloud', 'reportStoryAbuse', 'followSet', 14 // JAVASCRIPT-16WX: loadGroupInside only defined in v3 user template, missing in v4 15 'loadGroupInside', 16 // JAVASCRIPT-11P4: loadAjaxUrl not defined on all pages 17 'loadAjaxUrl']; 18 globalFunctions.forEach(function(fnName) { 19 if (typeof window[fnName] === 'undefined') { 20 window[fnName] = noop; 21 } 22 }); 23 24 // JAVASCRIPT-11HV / JAVASCRIPT-15Q: findTrack() stub must return object with setPosition 25 // so that callers like findTrack().setPosition(0) don't throw TypeError 26 if (typeof window.findTrack === 'undefined') { 27 window.findTrack = function() { 28 return { setPosition: noop, play: noop, pause: noop, stop: noop }; 29 }; 30 } 31 32 // playlist object stub â player.js defines window.playlist but it may not be ready yet 33 if (typeof window.playlist === 'undefined') { 34 window.playlist = { add: noop, remove: noop, next: noop, prev: noop }; 35 } 36 37 // JAVASCRIPT-Y3H: Promise.allSettled polyfill for older browsers (Firefox <71, Safari <13) 38 if (typeof Promise !== 'undefined' && typeof Promise.allSettled !== 'function') { 39 Promise.allSettled = function(promises) { 40 return Promise.all(promises.map(function(p) { 41 return Promise.resolve(p).then( 42 function(value) { return { status: 'fulfilled', value: value }; }, 43 function(reason) { return { status: 'rejected', reason: reason }; } 44 ); 45 })); 46 }; 47 } 48 49 // Hls.js stub â prevents crash when HLS library hasn't loaded yet 50 if (typeof window.Hls === 'undefined') { 51 window.Hls = { isSupported: function() { return false; }, Events: {}, ErrorDetails: {} }; 52 } 53 54 // Livestream global vars â set by AJAX response, default to 0 until response arrives 55 var livestreamVars = ['intRecording', 'intFacebook', 'intYoutube']; 56 livestreamVars.forEach(function(v) { 57 if (typeof window[v] === 'undefined') { window[v] = 0; } 58 }); 59 60 // l18n string stubs â fallback empty strings until js_language.php loads (Fixes JAVASCRIPT-119H class) 61 var globalStrings = [ 62 'l18nWriteCommentAt', 'l18nWriteReactionAt', 63 'l18nTimeAmPrefix', 'l18nTimeVorPrefix', 64 'l18nTimeVorSuffixT', 'l18nTimeVorSuffixTSingle', 65 'l18nTimeVorSuffixH', 'l18nTimeVorSuffixHSingle', 66 'l18nTimeVorSuffixM', 'l18nTimeVorSuffixMSingle', 67 'l18nTimeVorNow', 'l18nFollowAction', 'l18nFollow', 'l18nSendMessage' 68 ]; 69 globalStrings.forEach(function(varName) { 70 if (typeof window[varName] === 'undefined') { 71 window[varName] = ''; 72 } 73 }); 74})(); 75 76(function() { 77 'use strict'; 78 79 // Handle unhandledrejection events 80 window.addEventListener('unhandledrejection', function(event) { 81 // Filter out common user-intentional rejections 82 var reason = event.reason; 83 var reasonStr = String(reason); 84 85 // Filter out empty/undefined/null rejections that don't have meaningful error info 86 if (!reason || reasonStr === 'undefined' || reasonStr === 'null' || reasonStr === '' || reasonStr === '[object Object]') { 87 event.preventDefault(); 88 return; 89 } 90 91 // Common cancellations that should be silently ignored 92 var ignoredReasons = ['cancel', 'esc', 'overlay', 'close', 'dismiss']; 93 if (ignoredReasons.indexOf(reasonStr) !== -1 || ignoredReasons.indexOf(reasonStr.toLowerCase()) !== -1) { 94 event.preventDefault(); 95 return; 96 } 97 98 // Filter out external/browser extension errors that we cannot control 99 // These are typically from browser extensions or third-party scripts 100 var externalErrors = [ 101 'performanceMetrics', // Browser extension or third-party feature flag system 102 'cashbackReminder', // Third-party cashback extension (Fixes JAVA
102SCRIPT-11NG) 103 ]; 104 for (var i = 0; i < externalErrors.length; i++) { 105 if (reasonStr.indexOf(externalErrors[i]) !== -1) { 106 event.preventDefault(); 107 return; 108 } 109 } 110 111 // If the rejection reason is not an Error object, convert it 112 if (reason && !(reason instanceof Error)) { 113 // Create an error from the rejection value 114 var message = 'Promise rejection: ' + reasonStr; 115 var error = new Error(message); 116 error.originalReason = reason; 117 118 // Replace the reason with the error object 119 Object.defineProperty(event, 'reason', { 120 value: error, 121 writable: false, 122 configurable: true 123 }); 124 } 125 }, false); 126 127 // Also handle regular promise catches that might be passing non-Error values 128 // This patches Promise.prototype.catch to ensure proper error handling 129 if (Promise && Promise.prototype) { 130 var originalCatch = Promise.prototype.catch; 131 132 Promise.prototype.catch = function(onRejected) { 133 return originalCatch.call(this, function(reason) { 134 // If rejected with non-Error value, convert it 135 if (reason && !(reason instanceof Error)) { 136 reason = new Error('Promise rejection: ' + String(reason)); 137 } 138 139 // Call the original handler with the (possibly converted) reason 140 if (typeof onRejected === 'function') { 141 return onRejected(reason); 142 } 143 throw reason; 144 }); 145 }; 146 } 147 148 // Early stubs for common global functions to prevent ReferenceErrors during early user interaction 149 (function() { 150 var noop = function() {}; 151 // Includes functions defined in jsfooter (initialize15.js) called from PHP onclick handlers (Fixes JAVASCRIPT-119H class) 152 var stubs = ['play', 'pause', 'stop', 'countLike', 'countLikeSet', 'reFeed', 'reFeedSet', 'countCommentLike', 153 'closeLayer', 'getAllComments', 'setShare', 'loadMoreFeedStart', 'followUser', 'followGroup', 154 'ajaxLogin', 'loadAjaxUrl', 'calcTime']; 155 156 stubs.forEach(function(name) { 157 if (typeof window[name] === 'undefined') { 158 window[name] = function() { 159 var args = arguments; 160 var fnName = name; 161 if (window.jQuery && window.jQuery(document).ready) { 162 window.jQuery(document).ready(function() { 163 if (typeof window[fnName] === 'function' && window[fnName].toString().indexOf('native code') === -1) { 164 window[fnName].apply(null, args); 165 } 166 }); 167 } 168 }; 169 } 170 }); 171 172 // Guard for jQuery plugins and methods 173 if (window.jQuery) { 174 // Guard $.bridget (used by Isotope/Masonry) 175 if (typeof window.jQuery.bridget === 'undefined') { 176 window.jQuery.bridget = noop; 177 } 178 179 // Ensure common methods exist on jQuery prototype to prevent "is not a function" errors 180 var proto = window.jQuery.prototype; 181 var methods = ['text', 'off', 'on', 'hide', 'show', 'addClass', 'removeClass', 'attr', 'data', 'find', 'ajaxQueue', 'sortable', 'append', 'expander', 'typeahead', 'hovercard']; 182 methods.forEach(function(m) { 183 if (typeof proto[m] === 'undefined') { 184 proto[m] = function() { return this; }; 185 } 186 }); 187 188 // Guard $.ajaxQueue which is often used directly 189 if (typeof window.jQuery.ajaxQueue === 'undefined') { 190 window.jQuery.ajaxQueue = function() { return { done: noop, fail: noop, always: noop }; }; 191 } 192 193 // Wrap jQuery.globalEval to catch SyntaxErrors from malformed AJAX content 194 if (window.jQuery.globalEval) { 195 var originalGlobalEval = window.jQuery.globalEval; 196 window.jQuery.globalEval = function(code) { 197 try { 198 return originalGlobalEval.call(window.jQuery, code); 199 } catch (e) { 200 // Silently ignore syntax errors from malformed AJAX responses 201 if (e.name === 'SyntaxError') { 202 console.warn && console.warn('globalEval SyntaxError (ignored):', e.message); 203 return; 204 } 205 // Re-throw other errors 206 throw e; 207 } 208 }; 209 } 210 } 211 212 // Add defensive wrappers for document.querySelector/querySelectorAll 213 if (typeof document !== 'undefined') { 214 var originalQuerySelector = document.querySelector; 215 var originalQuerySelectorAll = document.querySelectorAll; 216 var originalGetElementById = document.getElementById; 217
218 // Wrap querySelector to handle null results safely 219 document.querySelector = function(selector) { 220 try { 221 return originalQuerySelector.call(document, selector); 222 } catch (e) { 223 // Ignore jQuery Migrate feature detection selectors 224 if (selector && selector.indexOf(':jqfake') === -1) { 225 console.warn && console.warn('querySelector error:', selector, e); 226 } 227 return null; 228 } 229 }; 230 231 // Wrap querySelectorAll to handle null results safely 232 document.querySelectorAll = function(selector) { 233 try { 234 return originalQuerySelectorAll.call(document, selector); 235 } catch (e) { 236 // Ignore jQuery Migrate feature detection selectors 237 if (selector && selector.indexOf(':jqfake') === -1) { 238 console.warn && console.warn('querySelectorAll error:', selector, e); 239 } 240 return []; 241 } 242 }; 243 244 // Wrap getElementById to handle null results safely 245 document.getElementById = function(id) { 246 try { 247 return originalGetElementById.call(document, id); 248 } catch (e) { 249 console.warn && console.warn('getElementById error:', id, e); 250 return null; 251 } 252 }; 253 } 254 255 // Note: Global function stubs (LIDNotifyId, findTrack, etc.) are now defined 256 // at the top of this file to prevent ReferenceErrors during early script execution 257 258 // Guard CodeMirror/SimpleMDE editor interactions 259 // Wrap event handlers that interact with editor instances to prevent "editor.trigger is not a function" errors 260 if (window.jQuery) { 261 // Intercept clicks on codemirror-user-suggest elements 262 window.jQuery(document).on('click', '.codemirror-user-suggest li', function(e) { 263 try { 264 // Find the associated editor instance 265 var editor = window.simplemde || window.editor; 266 if (editor && editor.codemirror && typeof editor.codemirror.trigger === 'function') { 267 editor.codemirror.trigger('change'); 268 } 269 } catch (err) { 270 console.warn && console.warn('CodeMirror editor interaction error (handled):', err); 271 // Prevent error from propagating 272 e.stopPropagation(); 273 e.preventDefault(); 274 } 275 }); 276 } 277 })(); 278})();
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.