Skip to content

Instantly share code, notes, and snippets.

@cymen
Created May 1, 2014 23:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cymen/645b8846bffbc182f1f3 to your computer and use it in GitHub Desktop.
Save cymen/645b8846bffbc182f1f3 to your computer and use it in GitHub Desktop.
! function(n) {
! function(n) {
function t(n, t) {
return Object.prototype.hasOwnProperty.call(n, t)
}
function e(n) {
return "undefined" == typeof n
}
var r = {},
i = n.TraceKit,
o = [].slice,
c = "?";
r.noConflict = function() {
return n.TraceKit = i, r
}, r.wrap = function(n) {
function t() {
try {
return n.apply(this, arguments)
} catch (t) {
throw r.report(t), t
}
}
return t
}, r.report = function() {
function e(n) {
l(), h.push(n)
}
function i(n) {
for (var t = h.length - 1; t >= 0; --t) h[t] === n && h.splice(t, 1)
}
function c(n, e) {
var i = null;
if (!e || r.collectWindowErrors) {
for (var c in h)
if (t(h, c)) try {
h[c].apply(null, [n].concat(o.call(arguments, 2)))
} catch (u) {
i = u
}
if (i) throw i
}
}
function u(n, t, e) {
var i = null;
if (m) r.computeStackTrace.augmentStackTraceWithInitialElement(m, t, e, n), i = m, m = null, p = null;
else {
var o = {
url: t,
line: e
};
o.func = r.computeStackTrace.guessFunctionName(o.url, o.line), o.context = r.computeStackTrace.gatherContext(o.url, o.line), i = {
mode: "onerror",
message: n,
url: document.location.href,
stack: [o],
useragent: navigator.userAgent
}
}
return c(i, "from window.onerror"), a ? a.apply(this, arguments) : !1
}
function l() {
f !== !0 && (a = n.onerror, n.onerror = u, f = !0)
}
function s(t) {
var e = o.call(arguments, 1);
if (m) {
if (p === t) return;
var i = m;
m = null, p = null, c.apply(null, [i, null].concat(e))
}
var u = r.computeStackTrace(t);
throw m = u, p = t, n.setTimeout(function() {
p === t && (m = null, p = null, c.apply(null, [u, null].concat(e)))
}, u.incomplete ? 2e3 : 0), t
}
var a, f, h = [],
p = null,
m = null;
return s.subscribe = e, s.unsubscribe = i, s
}(), r.computeStackTrace = function() {
function i(t) {
function e() {
try {
return new n.XMLHttpRequest
} catch (t) {
return new n.ActiveXObject("Microsoft.XMLHTTP")
}
}
if (!r.remoteFetching) return "";
try {
var i = e();
return i.open("GET", t, !1), i.send(""), i.responseText
} catch (o) {
return ""
}
}
function o(n) {
if (!t(w, n)) {
var e = ""; - 1 !== n.indexOf(document.domain) && (e = i(n)), w[n] = e ? e.split("\n") : []
}
return w[n]
}
function u(n, t) {
var r, i = /function ([^(]*)\(([^)]*)\)/,
u = /['"]?([0-9A-Za-z$_]+)['"]?\s*[:=]\s*(function|eval|new Function)/,
l = "",
s = 10,
a = o(n);
if (!a.length) return c;
for (var f = 0; s > f; ++f)
if (l = a[t - f] + l, !e(l)) {
if (r = u.exec(l)) return r[1];
if (r = i.exec(l)) return r[1]
}
return c
}
function l(n, t) {
var i = o(n);
if (!i.length) return null;
var c = [],
u = Math.floor(r.linesOfContext / 2),
l = u + r.linesOfContext % 2,
s = Math.max(0, t - u - 1),
a = Math.min(i.length, t + l - 1);
t -= 1;
for (var f = s; a > f; ++f) e(i[f]) || c.push(i[f]);
return c.length > 0 ? c : null
}
function s(n) {
return n.replace(/[\-\[\]{}()*+?.,\\\^$|#]/g, "\\$&")
}
function a(n) {
return s(n).replace("<", "(?:<|&lt;)").replace(">", "(?:>|&gt;)").replace("&", "(?:&|&amp;)").replace('"', '(?:"|&quot;)').replace(/\s+/g, "\\s+")
}
function f(n, t) {
for (var e, r, i = 0, c = t.length; c > i; ++i)
if ((e = o(t[i])).length && (e = e.join("\n"), r = n.exec(e))) return {
url: t[i],
line: e.substring(0, r.index).split("\n").length,
column: r.index - e.lastIndexOf("\n", r.index) - 1
};
return null
}
function h(n, t, e) {
var r, i = o(t),
c = new RegExp("\\b" + s(n) + "\\b");
return e -= 1, i && i.length > e && (r = c.exec(i[e])) ? r.index : null
}
function p(t) {
for (var e, r, i, o, c = [n.location.href], u = document.getElementsByTagName("script"), l = "" + t, h = /^function(?:\s+([\w$]+))?\s*\(([\w\s,]*)\)\s*\{\s*(\S[\s\S]*\S)\s*\}\s*$/, p = /^function on([\w$]+)\s*\(event\)\s*\{\s*(\S[\s\S]*\S)\s*\}\s*$/, m = 0; m < u.length; ++m) {
var g = u[m];
g.src && c.push(g.src)
}
if (i = h.exec(l)) {
var d = i[1] ? "\\s+" + i[1] : "",
v = i[2].split(",").join("\\s*,\\s*");
e = s(i[3]).replace(/;$/, ";?"), r = new RegExp("function" + d + "\\s*\\(\\s*" + v + "\\s*\\)\\s*{\\s*" + e + "\\s*}")
} else r = new RegExp(s(l).replace(/\s+/g, "\\s+")); if (o = f(r, c)) return o;
if (i = p.exec(l)) {
var x = i[1];
if (e = a(i[2]), r = new RegExp("on" + x + "=[\\'\"]\\s*" + e + "\\s*[\\'\"]", "i"), o = f(r, c[0])) return o;
if (r = new RegExp(e), o = f(r, c)) return o
}
return null
}
function m(n) {
if (!n.stack) return null;
for (var t, e, r = /^\s*at (?:((?:\[object object\])?\S+(?: \[as \S+\])?) )?\(?((?:file|http|https):.*?):(\d+)(?::(\d+))?\)?\s*$/i, i = /^\s*(\S*)(?:\((.*?)\))?@((?:file|http|https).*?):(\d+)(?::(\d+))?\s*$/i, o = n.stack.split("\n"), s = [], a = /^(.*) is undefined$/.exec(n.message), f = 0, p = o.length; p > f; ++f) {
if (t = i.exec(o[f])) e = {
url: t[3],
func: t[1] || c,
args: t[2] ? t[2].split(",") : "",
line: +t[4],
column: t[5] ? +t[5] : null
};
else {
if (!(t = r.exec(o[f]))) continue;
e = {
url: t[2],
func: t[1] || c,
line: +t[3],
column: t[4] ? +t[4] : null
}
}!e.func && e.line && (e.func = u(e.url, e.line)), e.line && (e.context = l(e.url, e.line)), s.push(e)
}
return s[0] && s[0].line && !s[0].column && a && (s[0].column = h(a[1], s[0].url, s[0].line)), s.length ? {
mode: "stack",
name: n.name,
message: n.message,
url: document.location.href,
stack: s,
useragent: navigator.userAgent
} : null
}
function g(n) {
for (var t, e = n.stacktrace, r = / line (\d+), column (\d+) in (?:<anonymous function: ([^>]+)>|([^\)]+))\((.*)\) in (.*):\s*$/i, i = e.split("\n"), o = [], c = 0, s = i.length; s > c; c += 2)
if (t = r.exec(i[c])) {
var a = {
line: +t[1],
column: +t[2],
func: t[3] || t[4],
args: t[5] ? t[5].split(",") : [],
url: t[6]
};
if (!a.func && a.line && (a.func = u(a.url, a.line)), a.line) try {
a.context = l(a.url, a.line)
} catch (f) {}
a.context || (a.context = [i[c + 1]]), o.push(a)
}
return o.length ? {
mode: "stacktrace",
name: n.name,
message: n.message,
url: document.location.href,
stack: o,
useragent: navigator.userAgent
} : null
}
function d(e) {
var r = e.message.split("\n");
if (r.length < 4) return null;
var i, c, s, h, p = /^\s*Line (\d+) of linked script ((?:file|http|https)\S+)(?:: in function (\S+))?\s*$/i,
m = /^\s*Line (\d+) of inline#(\d+) script in ((?:file|http|https)\S+)(?:: in function (\S+))?\s*$/i,
g = /^\s*Line (\d+) of function script\s*$/i,
d = [],
v = document.getElementsByTagName("script"),
x = [];
for (c in v) t(v, c) && !v[c].src && x.push(v[c]);
for (c = 2, s = r.length; s > c; c += 2) {
var y = null;
if (i = p.exec(r[c])) y = {
url: i[2],
func: i[3],
line: +i[1]
};
else if (i = m.exec(r[c])) {
y = {
url: i[3],
func: i[4]
};
var k = +i[1],
b = x[i[2] - 1];
if (b && (h = o(y.url))) {
h = h.join("\n");
var w = h.indexOf(b.innerText);
w >= 0 && (y.line = k + h.substring(0, w).split("\n").length)
}
} else if (i = g.exec(r[c])) {
var T = n.location.href.replace(/#.*$/, ""),
_ = i[1],
E = new RegExp(a(r[c + 1]));
h = f(E, [T]), y = {
url: T,
line: h ? h.line : _,
func: ""
}
}
if (y) {
y.func || (y.func = u(y.url, y.line));
var S = l(y.url, y.line),
j = S ? S[Math.floor(S.length / 2)] : null;
y.context = S && j.replace(/^\s*/, "") === r[c + 1].replace(/^\s*/, "") ? S : [r[c + 1]], d.push(y)
}
}
return d.length ? {
mode: "multiline",
name: e.name,
message: r[0],
url: document.location.href,
stack: d,
useragent: navigator.userAgent
} : null
}
function v(n, t, e, r) {
var i = {
url: t,
line: e
};
if (i.url && i.line) {
n.incomplete = !1, i.func || (i.func = u(i.url, i.line)), i.context || (i.context = l(i.url, i.line));
var o = / '([^']+)' /.exec(r);
if (o && (i.column = h(o[1], i.url, i.line)), n.stack.length > 0 && n.stack[0].url === i.url) {
if (n.stack[0].line === i.line) return !1;
if (!n.stack[0].line && n.stack[0].func === i.func) return n.stack[0].line = i.line, n.stack[0].context = i.context, !1
}
return n.stack.unshift(i), n.partial = !0, !0
}
return n.incomplete = !0, !1
}
function x(n, t) {
for (var e, i, o, l = /function\s+([_$a-zA-Z\xA0-\uFFFF][_$a-zA-Z0-9\xA0-\uFFFF]*)?\s*\(/i, s = [], a = {}, f = !1, m = x.caller; m && !f; m = m.caller)
if (m !== y && m !== r.report) {
if (i = {
url: null,
func: c,
line: null,
column: null
}, m.name ? i.func = m.name : (e = l.exec(m.toString())) && (i.func = e[1]), o = p(m)) {
i.url = o.url, i.line = o.line, i.func === c && (i.func = u(i.url, i.line));
var g = / '([^']+)' /.exec(n.message || n.description);
g && (i.column = h(g[1], o.url, o.line))
}
a["" + m] ? f = !0 : a["" + m] = !0, s.push(i)
}
t && s.splice(0, t);
var d = {
mode: "callers",
name: n.name,
message: n.message,
url: document.location.href,
stack: s,
useragent: navigator.userAgent
};
return v(d, n.sourceURL || n.fileName, n.line || n.lineNumber, n.message || n.description), d
}
function y(n, t) {
var e = null;
t = null == t ? 0 : +t;
try {
if (e = g(n)) return e
} catch (r) {
if (b) throw r
}
try {
if (e = m(n)) return e
} catch (r) {
if (b) throw r
}
try {
if (e = d(n)) return e
} catch (r) {
if (b) throw r
}
try {
if (e = x(n, t + 1)) return e
} catch (r) {
if (b) throw r
}
return {
mode: "failed"
}
}
function k(n) {
n = (null == n ? 0 : +n) + 1;
try {
throw new Error
} catch (t) {
return y(t, n + 1)
}
return null
}
var b = !1,
w = {};
return y.augmentStackTraceWithInitialElement = v, y.guessFunctionName = u, y.gatherContext = l, y.ofCaller = k, y
}(), ! function() {
var t = function(t) {
var e = n[t];
n[t] = function() {
var n = o.call(arguments),
t = n[0];
return "function" == typeof t && (n[0] = r.wrap(t)), e.apply ? e.apply(this, n) : e(n[0], n[1])
}
};
t("setTimeout"), t("setInterval")
}(), r.remoteFetching || (r.remoteFetching = !0), r.collectWindowErrors || (r.collectWindowErrors = !0), (!r.linesOfContext || r.linesOfContext < 1) && (r.linesOfContext = 11), n.TraceKit = r
}(n);
var t;
t = function() {
function t(n) {
var t, e, r;
null == n && (n = {}), r = this.constructor.defaults;
for (t in r) e = r[t], this[t] = e;
for (t in n) e = n[t], this[t] = e
}
return t.defaults = {
api_key: null,
host: "api.honeybadger.io",
ssl: !0,
project_root: n.location.protocol + "//" + n.location.host,
environment: "production",
component: null,
action: null,
disabled: !0,
onerror: !1
}, t.prototype.reset = function() {
var n, t, e;
e = this.constructor.defaults;
for (n in e) t = e[n], this[n] = t;
return this
}, t
}();
var e;
e = function() {
function n(n) {
var t, e, i, o, c, u, l;
this.options = null != n ? n : {}, this.error = this.options.error, this.stackInfo = this.options.stackInfo || this.error && r.TraceKit.computeStackTrace(this.error), this.trace = this._parseBacktrace(null != (i = this.stackInfo) ? i.stack : void 0), this["class"] = null != (o = this.stackInfo) ? o.name : void 0, this.message = null != (c = this.stackInfo) ? c.message : void 0, this.source = this.stackInfo && this._extractSource(this.stackInfo.stack), this.url = document.URL, this.project_root = r.configuration.project_root, this.environment = r.configuration.environment, this.component = r.configuration.component, this.action = r.configuration.action, this.context = {}, u = r.context;
for (t in u) e = u[t], this.context[t] = e;
if (this.options.context && "object" == typeof this.options.context) {
l = this.options.context;
for (t in l) e = l[t], this.context[t] = e
}
}
return n.prototype.toJSON = function() {
return JSON.stringify({
notifier: {
name: "honeybadger.js",
url: "https://github.com/honeybadger-io/honeybadger-js",
version: r.version,
language: "javascript"
},
error: {
"class": this["class"],
message: this.message,
backtrace: this.trace,
source: this.source
},
request: {
url: this.url,
component: this.component,
action: this.action,
context: this.context,
cgi_data: this._cgiData()
},
server: {
project_root: this.project_root,
environment_name: this.environment
}
})
}, n.prototype._parseBacktrace = function(n) {
var t, e, i, o, c, u;
for (null == n && (n = []), t = [], i = 0, o = n.length; o > i; i++) e = n[i], (null != (c = e.url) ? c.match(/honeybadger(?:\.min)?\.js/) : 0) || t.push({
file: (null != (u = e.url) ? u.replace(r.configuration.project_root, "[PROJECT_ROOT]") : void 0) || "unknown",
number: e.line,
method: e.func
});
return t
}, n.prototype._extractSource = function(n) {
var t, e, r, i, o, c, u, l;
for (null == n && (n = []), r = {}, l = null != (c = null != (u = n[0]) ? u.context : void 0) ? c : [], t = i = 0, o = l.length; o > i; t = ++i) e = l[t], r[t] = e;
return r
}, n.prototype._cgiData = function() {
var n, t, e;
n = {};
for (t in navigator) e = navigator[t], e instanceof Object || (n[t.split(/(?=[A-Z][a-z]*)/).join("_").toUpperCase()] = e);
return n.HTTP_USER_AGENT = n.USER_AGENT, delete n.USER_AGENT, document.referrer.match(/\S/) && (n.HTTP_REFERER = document.referrer), n
}, n
}();
var r, i = {}.hasOwnProperty;
r = {
version: "0.0.4",
TraceKit: TraceKit.noConflict(),
configured: !1,
configure: function(n) {
var t, e;
null == n && (n = {}), this.configured === !1 && ("undefined" == typeof n.disabled && (n.disabled = !1), this.configured = !0);
for (t in n) e = n[t], this.configuration[t] = e;
return this.TraceKit.collectWindowErrors = this.configuration.onerror, this
},
configuration: new t,
context: {},
resetContext: function(n) {
return null == n && (n = {}), this.context = n instanceof Object ? n : {}, this
},
setContext: function(n) {
var t, e;
if (null == n && (n = {}), n instanceof Object)
for (t in n) e = n[t], this.context[t] = e;
return this
},
beforeNotifyHandlers: [],
beforeNotify: function(n) {
return this.beforeNotifyHandlers.push(n)
},
notify: function(n, t) {
var r, o, c, u, l, s, a;
if (null == t && (t = {}), !this.configured || this.configuration.disabled === !0) return !1;
if (n instanceof Error) t.error = n;
else if ("string" == typeof n) t.error = new Error(n);
else if (n instanceof Object)
for (o in n) u = n[o], t[o] = u;
if (0 === function() {
var n;
n = [];
for (o in t) i.call(t, o) && n.push(o);
return n
}().length) return !1;
for (c = new e(t), a = this.beforeNotifyHandlers, l = 0, s = a.length; s > l; l++)
if (r = a[l], r(c) === !1) return !1;
return this._sendRequest(c.toJSON())
},
wrap: function(n) {
return function() {
var t;
try {
return n.apply(this, arguments)
} catch (e) {
throw t = e, r.notify(t), t
}
}
},
reset: function() {
return this.resetContext(), this.configuration.reset(), this.TraceKit.collectWindowErrors = this.configuration.onerror, this.configured = !1, this
},
install: function() {
return this.TraceKit.collectWindowErrors = this.configuration.onerror, this.TraceKit.report.subscribe(this._handleTraceKitSubscription), this
},
_sendRequest: function(n) {
var t;
return t = "http" + (this.configuration.ssl && "s" || "") + "://" + this.configuration.host + "/v1/notices.html", this._crossDomainPost(t, n)
},
_crossDomainPost: function(n, t) {
var e, r, i, o;
return r = document.createElement("iframe"), o = "_hb_" + (new Date).getTime(), document.body.appendChild(r), r.style.display = "none", r.contentWindow.name = o, e = document.createElement("form"), e.target = o, e.action = n, e.method = "POST", i = document.createElement("input"), i.type = "hidden", i.name = "payload", i.value = t, e.appendChild(i), i = document.createElement("input"), i.type = "hidden", i.name = "api_key", i.value = this.configuration.api_key, e.appendChild(i), document.body.appendChild(e), e.submit()
},
_handleTraceKitSubscription: function(n) {
return r.notify({
stackInfo: n
})
}
}, n.Honeybadger = r, r.install()
}(window);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment