Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save devinrhode2/1d78c1b67ba1a94ee9a5c9d5cd31ff66 to your computer and use it in GitHub Desktop.
Save devinrhode2/1d78c1b67ba1a94ee9a5c9d5cd31ff66 to your computer and use it in GitHub Desktop.
<script src="https://browser.sentry-cdn.com/4.2.4/bundle.min.js" crossorigin="anonymous"
onerror="if(confirm('Connection lost\n\nReload?')) location.reload();"></script>
<script>
// String.includes polyfill from https://mths.be/includes v1.0.0 by @mathias
if (!String.prototype.includes) {
(function() {
'use strict'; // needed to support `apply`/`call` with `undefined`/`null`
var toString = {}.toString;
var defineProperty = (function() {
// IE 8 only supports `Object.defineProperty` on DOM elements
try {
var object = {};
var $defineProperty = Object.defineProperty;
var result = $defineProperty(object, object, object) && $defineProperty;
} catch(error) {}
return result;
}());
var indexOf = ''.indexOf;
var includes = function(search) {
if (this == null) {
throw TypeError();
}
var string = String(this);
if (search && toString.call(search) == '[object RegExp]') {
throw TypeError();
}
var stringLength = string.length;
var searchString = String(search);
var searchLength = searchString.length;
var position = arguments.length > 1 ? arguments[1] : undefined;
// `ToInteger`
var pos = position ? Number(position) : 0;
if (pos != pos) { // better `isNaN`
pos = 0;
}
var start = Math.min(Math.max(pos, 0), stringLength);
// Avoid the `indexOf` call if no match is possible
if (searchLength + start > stringLength) {
return false;
}
return indexOf.call(string, searchString, pos) != -1;
};
if (defineProperty) {
defineProperty(String.prototype, 'includes', {
'value': includes,
'configurable': true,
'writable': true
});
} else {
String.prototype.includes = includes;
}
}());
}
if (!location.href.includes('local')) {
Sentry.init({ dsn: 'https://XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX@sentry.io/0000000' });
}
// creating function declarations for better stacktraces (otherwise they'd be anonymous function expressions)
var oldConsoleError = console.error;
var oldConsoleWarn = console.warn;
console.plainWarn = oldConsoleWarn.bind(console);
console.plainError = oldConsoleError.bind(console);
function console_error() {
var err = createNiceError(arguments);
Sentry.captureException(err, { level: 'error' });
return oldConsoleError.call(console, err);
}
function console_warn() {
var err = createNiceError(arguments);
Sentry.captureMessage(err, { level: 'warning' });
return oldConsoleWarn.call(console, err);
}
console.error = console_error;
console.warn = console_warn;
function maybeToString(thing) {
if (thing != null) {
return thing.toString ? thing.toString() : thing+'';
} else {
return thing;
}
}
function createNiceError(args) {
let errorMsg = args[0];
// Make sure errorMsg is either an error or string.
// It's therefore best to pass in new Error('msg') instead of just 'msg' since
// that'll give you a stack trace leading up to the creation of that new Error
// whereas if you just pass in a plain string 'msg', the stack trace will include
// console_error and console_call
if (errorMsg == null) { errorMsg = errorMsg + ''; }
var split = errorMsg.split('\n');
if (errorMsg.stack) {
errorMsg = errorMsg.stack;
} else if (errorMsg.stacktrace) {
errorMsg = errorMsg.stacktrace;
} else if (split && split[0] && split[0].includes('Error: ') && errorMsg.split('\n').length > 2 && errorMsg.includes('.js')) {
// Looks like this is already a stack trace string,
// in which case we'll do nothing.
} else {
// errorMsg has no stack property, presumably it's a string
// so it should NOT be an instanceof Error
// (this should really be a separate test)
if (errorMsg instanceof Error) {
// wow it's an Error but doesn't have a stack property...
oldConsoleError.apply(
console,
[
new Error(
'Error in createNiceError, errorMsg has no stack prop but is an instanceof Error. errorMsg as string:'+errorMsg
),
'\n\nerrorMsg as object:',
errorMsg
]
);
}
// stringify all args as a new Error, and grab stack trace
args = Array.prototype.slice.call(args);
errorMsg = new Error(
args.reduce(function(accumulator, currentValue) {
return ((
accumulator !== '' ? maybeToString(accumulator) : ''
) + maybeToString(currentValue) );
}, '')
).stack;
}
errorMsg = errorMsg.replace(/\n.+createNiceError.+/g, '')
errorMsg = errorMsg.replace(/\n.+console_warn.+/g, '')
errorMsg = errorMsg.replace(/\n.+console_error.+/g, '')
// by including "Error: " in the beginning, chrome pretty-prints the file names in the stack trace :)
// if (errorMsg.includes('selected nothing. Do $(\'')) {
// var toRemove = 'Error: ';
// console.log
// if (errorMsg.indexOf('Error: ') === 0) {
// errorMsg = errorMsg.substring(toRemove.length-1, errorMsg.length);
// // errorMsg = errorMsg.replace('Error: $(\'', '$(\'');
// }
// }
return errorMsg;
}
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment