UNPKG

raven-js

Version:
80 lines (70 loc) 3.33 kB
(function(_window, _document, _script, _onerror, _onunhandledrejection) { var SENTRY_SDK = _window.SENTRY_SDK; // Create a namespace and attach function that will store captured exception // Because functions are also objects, we can attach the queue itself straight to it and save some bytes var queue = function(exception) { queue.data.push(exception); }; queue.data = []; // Store reference to the old `onerror` handler and override it with our own function // that will just push exceptions to the queue and call through old handler if we found one var _oldOnerror = _window[_onerror]; _window[_onerror] = function(message, source, lineno, colno, exception) { // Use keys as "data type" to save some characters" queue({ e: [].slice.call(arguments) }); if (_oldOnerror) _oldOnerror.apply(_window, arguments); }; // Do the same store/queue/call operations for `onunhandledrejection` event var _oldOnunhandledrejection = _window[_onunhandledrejection]; _window[_onunhandledrejection] = function(exception) { queue({ p: exception.reason }); if (_oldOnunhandledrejection) _oldOnunhandledrejection.apply(_window, arguments); }; // Create a `script` tag with provided SDK `url` and attach it just before the first, already existing `script` tag // Scripts that are dynamically created and added to the document are async by default, // they don't block rendering and execute as soon as they download, meaning they could // come out in the wrong order. Because of that we don't need async=1 as GA does. // it was probably(?) a legacy behavior that they left to not modify few years old snippet // https://www.html5rocks.com/en/tutorials/speed/script-loading/ var _currentScriptTag = _document.getElementsByTagName(_script)[0]; var _newScriptTag = _document.createElement(_script); _newScriptTag.src = SENTRY_SDK.url; _newScriptTag.crossorigin = 'anonymous'; // Once our SDK is loaded _newScriptTag.addEventListener('load', function() { try { // Restore onerror/onunhandledrejection handlers _window[_onerror] = _oldOnerror; _window[_onunhandledrejection] = _oldOnunhandledrejection; var data = queue.data; var SDK = _window.Raven; // Configure it using provided DSN and config object SDK.config(SENTRY_SDK.dsn, SENTRY_SDK.options).install(); // Because we installed the SDK, at this point we have an access to TraceKit's handler, // which can take care of browser differences (eg. missing exception argument in onerror) var tracekitErrorHandler = _window[_onerror]; // And capture all previously caught exceptions if (data.length) { for (var i = 0; i < data.length; i++) { if (data[i].e) { tracekitErrorHandler.apply(SDK.TraceKit, data[i].e); } else if (data[i].p) { SDK.captureException(data[i].p); } } } } catch (o_O) { console.log(o_O); } }); // Markers used to remove setTimeout (used for testing) from prod build, DO NOT REMOVE // build_marker setTimeout(function() { _currentScriptTag.parentNode.insertBefore(_newScriptTag, _currentScriptTag); // build_marker }, 500); })(window, document, 'script', 'onerror', 'onunhandledrejection');