Created
November 30, 2018 16:28
-
-
Save devinrhode2/1d78c1b67ba1a94ee9a5c9d5cd31ff66 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<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