Skip to content

Instantly share code, notes, and snippets.

@dustinlarimer
Last active August 12, 2019 04:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save dustinlarimer/9908181 to your computer and use it in GitHub Desktop.
Save dustinlarimer/9908181 to your computer and use it in GitHub Desktop.
JS Error Reporting with Keen IO
<!DOCTYPE html>
<html>
<head>
<script src="keen-3.0.0.track.min.js"></script>
<script src="keen-reporter.js"></script>
<script>
!function(){
var keen = new Keen({
projectId: "",
writeKey: "",
requestType: "beacon",
js_reporter: true
});
}();
</script>
<script src="trigger-error.js"></script>
</head>
<body></body>
</html>
!function(a,b,c){"undefined"!=typeof module&&module.exports?module.exports=c():"function"==typeof define&&define.amd?define(c):b[a]=c()}("Keen",this,function(){"use strict";function Keen(){return _init.apply(this,arguments)}function _init(a){if(_isUndefined(a))throw new Error("Check out our JavaScript SDK Usage Guide: https://keen.io/docs/clients/javascript/usage-guide/");if(_isUndefined(a.projectId)||"string"!=typeof a.projectId||a.projectId.length<1)throw new Error("Please provide a projectId");this.configure(a)}function _extend(a){for(var b=1;b<arguments.length;b++)for(var c in arguments[b])a[c]=arguments[b][c];return a}function _isUndefined(a){return void 0===a}function _type(a){var b=a.constructor.toString();return b.match(/function (.*)\(/)[1]}function _set_protocol(a){switch(a){case"http":return"http";case"auto":return location.protocol.replace(/:/g,"");case"https":case void 0:default:return"https"}}function _set_request_type(a){var b=a||"xhr",c=!1;return("object"==typeof XMLHttpRequest||"function"==typeof XMLHttpRequest)&&"withCredentials"in new XMLHttpRequest&&(c=!0),null==b||"xhr"==b?c?"xhr":"jsonp":b}function _build_url(a){return this.client.endpoint+"/projects/"+this.client.projectId+a}function _uploadEvent(a,b,c,d){var e=_build_url.apply(this,["/events/"+a]),f={};this.client.globalProperties&&(f=this.client.globalProperties(a));for(var g in b)b.hasOwnProperty(g)&&(f[g]=b[g]);switch(this.client.requestType){case"xhr":_request.xhr.apply(this,["POST",e,null,f,this.client.writeKey,c,d]);break;case"jsonp":var h=JSON.stringify(f),i=Keen.Base64.encode(h);e=e+"?api_key="+this.client.writeKey,e=e+"&data="+i,e=e+"&modified="+(new Date).getTime(),_request.jsonp.apply(this,[e,this.client.writeKey,c,d]);break;case"beacon":var h=JSON.stringify(f),i=Keen.Base64.encode(h);e=e+"?api_key="+encodeURIComponent(this.client.writeKey),e=e+"&data="+encodeURIComponent(i),e=e+"&modified="+encodeURIComponent((new Date).getTime()),e+="&c=clv1",_request.beacon.apply(this,[e,null,c,d])}}Keen.prototype.configure=function(a){return a.host=_isUndefined(a.host)?"api.keen.io/3.0":a.host.replace(/.*?:\/\//g,""),a.protocol=_set_protocol(a.protocol),a.requestType=_set_request_type(a.requestType),this.client={projectId:a.projectId,writeKey:a.writeKey,readKey:a.readKey,globalProperties:null,endpoint:a.protocol+"://"+a.host,requestType:a.requestType},Keen.trigger("client",this,a),this.trigger("ready"),this};var _request={xhr:function(a,b,c,d,e,f,g,h){if(!e)return Keen.log("Please provide a writeKey for https://keen.io/project/"+this.client.projectId);var i=new XMLHttpRequest;if(i.onreadystatechange=function(){if(4==i.readyState)if(i.status>=200&&i.status<300){var a,b={};try{a=JSON.parse(i.responseText),"number"==typeof h&&(b.sequence=h)}catch(c){Keen.log("Could not JSON parse HTTP response: "+i.responseText),g&&g(i,c)}f&&a&&f(a,b)}else Keen.log("HTTP request failed."),g&&g(i,null)},i.open(a,b,!0),e&&i.setRequestHeader("Authorization",e),d&&i.setRequestHeader("Content-Type","application/json"),c)for(var j in c)c.hasOwnProperty(j)&&i.setRequestHeader(j,c[j]);var k=d?JSON.stringify(d):null;i.send(k)},jsonp:function(a,b,c,d,e){if(!b)return Keen.log("Please provide a writeKey for https://keen.io/project/"+this.client.projectId);if(b&&a.indexOf("api_key")<0){var f=a.indexOf("?")>0?"&":"?";a=a+f+"api_key="+b}for(var g="keenJSONPCallback"+(new Date).getTime();g in window;)g+="a";var h,i=!1;window[g]=function(a){i=!0,h={},c&&a&&("number"==typeof e&&(h.sequence=e),c(a,h)),window[g]=void 0},a=a+"&jsonp="+g;var j=document.createElement("script");j.id="keen-jsonp",j.src=a,document.getElementsByTagName("head")[0].appendChild(j),j.onreadystatechange=function(){i===!1&&"loaded"===this.readyState&&(i=!0,d&&d())},j.onerror=function(){i===!1&&(i=!0,d&&d())}},beacon:function(a,b,c,d){if(b&&a.indexOf("api_key")<0){var e=a.indexOf("?")>0?"&":"?";a=a+e+"api_key="+b}var f=!1,g=document.createElement("img");g.onload=function(){if(f=!0,"naturalHeight"in this){if(this.naturalHeight+this.naturalWidth===0)return void this.onerror()}else if(this.width+this.height===0)return void this.onerror();c&&c({created:!0})},g.onerror=function(){f=!0,d&&d()},g.src=a}},Events=Keen.Events={on:function(a,b){this.listeners||(this.listeners={});var c=this.listeners[a]||(this.listeners[a]=[]);return c.push({callback:b}),this},off:function(a,b){if(!a&&!b)return this.listeners=void 0,delete this.listeners,this;for(var c=this.listeners[a]||[],d=c.length;d--;)b&&b==c[d].callback&&this.listeners[a].splice(d,1),b&&0!=c.length||(this.listeners[a]=void 0,delete this.listeners[a]);return this},trigger:function(a){if(!this.listeners)return this;for(var b=Array.prototype.slice.call(arguments,1),c=this.listeners[a]||[],d=0;d<c.length;d++)c[d].callback.apply(this,b);return this}};_extend(Keen.prototype,Events),_extend(Keen,Events);var Plugins=Keen.Plugins={};Keen.prototype.addEvent=function(){_uploadEvent.apply(this,arguments)},Keen.prototype.trackExternalLink=function(a,b,c,d,e){void 0===d&&(d=500);var f=!1,g=function(){};return"A"===a.nodeName?g=function(){f||(f=!0,window.location=a.href)}:"FORM"===a.nodeName&&(g=function(){f||(f=!0,a.submit())}),e&&(g=function(){f||(f=!0,e())}),_uploadEvent.apply(this,arguments),setTimeout(function(){g()},d),!1},Keen.prototype.setGlobalProperties=function(a){if(!this.client)return Keen.log("Check out our JavaScript SDK Usage Guide: https://keen.io/docs/clients/javascript/usage-guide/");if(!a||"function"!=typeof a)throw new Error("Invalid value for global properties: "+a);this.client.globalProperties=a};var AsyncLoading=Keen.Plugins.AsyncLoading=function(){var a=window._Keen||!1;if(a){var b=a.clients||{},c=a.ready||[];for(var d in b)if(b.hasOwnProperty(d)){var e=b[d];for(var f in Keen.prototype)Keen.prototype.hasOwnProperty(f)&&(window.Keen.prototype[f]=Keen.prototype[f]);for(var g=["Analysis","Count","CountUnique","Sum","Average","Minimum","Maximum","SelectUnique","Extraction","Funnel"],h=0;h<g.length;h++)window.Keen[g[h]]=Keen.Query?Keen[g[h]]:function(){throw new Error("Keen."+g[h]+" is not available in this version of the library.")};if(e._config&&(e.configure(e._config),delete e._config),e._setGlobalProperties){for(var i=e._setGlobalProperties,h=0;h<i.length;h++)e.setGlobalProperties.apply(e,i[h]);delete e._setGlobalProperties}if(e._addEvent){for(var j=e._addEvent||[],h=0;h<j.length;h++)e.addEvent.apply(e,j[h]);delete e._addEvent}var k=e._on||[];if(e._on){for(var h=0;h<k.length;h++)e.on.apply(e,k[h]);e.trigger("ready"),delete e._on}}for(var h=0;h<c.length;h++){var k=c[h];Keen.on("ready",function(){k()})}}};return Keen.on("ready",function(){Keen.Plugins.AsyncLoading()}),Keen.Base64={map:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",encode:function(a){var b,c,d,e,f,g,h,i="",j=0,k=this.map;for(a=this.utf8.encode(a);j<a.length;)b=a.charCodeAt(j++),c=a.charCodeAt(j++),d=a.charCodeAt(j++),e=b>>2,f=(3&b)<<4|c>>4,g=isNaN(c)?64:(15&c)<<2|d>>6,h=isNaN(c)||isNaN(d)?64:63&d,i=i+k.charAt(e)+k.charAt(f)+k.charAt(g)+k.charAt(h);return i},decode:function(a){var b,c,d,e,f,g,h,i="",j=0,k=this.map,l=String.fromCharCode;for(a=a.replace(/[^A-Za-z0-9\+\/\=]/g,"");j<a.length;)b=k.indexOf(a.charAt(j++)),c=k.indexOf(a.charAt(j++)),d=k.indexOf(a.charAt(j++)),e=k.indexOf(a.charAt(j++)),f=b<<2|c>>4,g=(15&c)<<4|d>>2,h=(3&d)<<6|e,i=i+(l(f)+(64!=d?l(g):""))+(64!=e?l(h):"");return this.utf8.decode(i)},utf8:{encode:function(a){for(var b,c="",d=0,e=String.fromCharCode;d<a.length;)b=a.charCodeAt(d++),c+=128>b?e(b):b>127&&2048>b?e(b>>6|192)+e(63&b|128):e(b>>12|224)+e(b>>6&63|128)+e(63&b|128);return c},decode:function(a){for(var b,c,d="",e=0,f=String.fromCharCode;e<a.length;)c=a.charCodeAt(e),d+=128>c?[f(c),e++][0]:c>191&&224>c?[f((31&c)<<6|63&(b=a.charCodeAt(e+1))),e+=2][0]:[f((15&c)<<12|(63&(b=a.charCodeAt(e+1)))<<6|63&(c3=a.charCodeAt(e+2))),e+=3][0];return d}}},"object"!=typeof JSON&&(JSON={}),function(){function f(a){return 10>a?"0"+a:a}function quote(a){return escapable.lastIndex=0,escapable.test(a)?'"'+a.replace(escapable,function(a){var b=meta[a];return"string"==typeof b?b:"\\u"+("0000"+a.charCodeAt(0).toString(16)).slice(-4)})+'"':'"'+a+'"'}function str(a,b){var c,d,e,f,g,h=gap,i=b[a];switch(i&&"object"==typeof i&&"function"==typeof i.toJSON&&(i=i.toJSON(a)),"function"==typeof rep&&(i=rep.call(b,a,i)),typeof i){case"string":return quote(i);case"number":return isFinite(i)?String(i):"null";case"boolean":case"null":return String(i);case"object":if(!i)return"null";if(gap+=indent,g=[],"[object Array]"===Object.prototype.toString.apply(i)){for(f=i.length,c=0;f>c;c+=1)g[c]=str(c,i)||"null";return e=0===g.length?"[]":gap?"[\n"+gap+g.join(",\n"+gap)+"\n"+h+"]":"["+g.join(",")+"]",gap=h,e}if(rep&&"object"==typeof rep)for(f=rep.length,c=0;f>c;c+=1)"string"==typeof rep[c]&&(d=rep[c],e=str(d,i),e&&g.push(quote(d)+(gap?": ":":")+e));else for(d in i)Object.prototype.hasOwnProperty.call(i,d)&&(e=str(d,i),e&&g.push(quote(d)+(gap?": ":":")+e));return e=0===g.length?"{}":gap?"{\n"+gap+g.join(",\n"+gap)+"\n"+h+"}":"{"+g.join(",")+"}",gap=h,e}}"function"!=typeof Date.prototype.toJSON&&(Date.prototype.toJSON=function(){return isFinite(this.valueOf())?this.getUTCFullYear()+"-"+f(this.getUTCMonth()+1)+"-"+f(this.getUTCDate())+"T"+f(this.getUTCHours())+":"+f(this.getUTCMinutes())+":"+f(this.getUTCSeconds())+"Z":null},String.prototype.toJSON=Number.prototype.toJSON=Boolean.prototype.toJSON=function(){return this.valueOf()});var cx=/[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,escapable=/[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,gap,indent,meta={"\b":"\\b"," ":"\\t","\n":"\\n","\f":"\\f","\r":"\\r",'"':'\\"',"\\":"\\\\"},rep;"function"!=typeof JSON.stringify&&(JSON.stringify=function(a,b,c){var d;if(gap="",indent="","number"==typeof c)for(d=0;c>d;d+=1)indent+=" ";else"string"==typeof c&&(indent=c);if(rep=b,b&&"function"!=typeof b&&("object"!=typeof b||"number"!=typeof b.length))throw new Error("JSON.stringify");return str("",{"":a})}),"function"!=typeof JSON.parse&&(JSON.parse=function(text,reviver){function walk(a,b){var c,d,e=a[b];if(e&&"object"==typeof e)for(c in e)Object.prototype.hasOwnProperty.call(e,c)&&(d=walk(e,c),void 0!==d?e[c]=d:delete e[c]);return reviver.call(a,b,e)}var j;if(text=String(text),cx.lastIndex=0,cx.test(text)&&(text=text.replace(cx,function(a){return"\\u"+("0000"+a.charCodeAt(0).toString(16)).slice(-4)})),/^[\],:{}\s]*$/.test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,"@").replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,"]").replace(/(?:^|:|,)(?:\s*\[)+/g,"")))return j=eval("("+text+")"),"function"==typeof reviver?walk({"":j},""):j;throw new SyntaxError("JSON.parse")})}(),Keen.domReady="function"==typeof $?$:function(a){a()},Keen.ready=function(a){Keen.on("ready",Keen.domReady(function(){a()}))},Keen.trigger("ready"),Keen.log=function(a){console.log("[Keen IO]",a)},Keen});
!function(name, context){
var Keen = context[name], logger;
Keen.on('client', function(client, config){
if (config.js_reporter) {
logger = client;
init();
}
});
/* Browsers supporting window.onerror
-----------------------------------
Chrome 13+
Firefox 6.0+
Internet Explorer 5.5+
Opera 11.60+
Safari 5.1+
*/
function init(){
// Set up error listener
if (window.addEventListener) {
window.addEventListener("error", handleException, false);
} else if (window.attachEvent) {
window.attachEvent('onpropertychange', function(e) {
if (e.propertyName == "error") {
handleException.apply(this, arguments);
}
});
} else {
window.onerror = function(message, url, line, col, ref) {
handleException({
message: message,
url: url,
line_no: line,
col_no: (col) ? col : null,
stack: (ref && ref.stack) ? ref.stack : null
});
};
}
}
function handleException(error) {
//console.log(error);
var message,
report = {
bubbles: ("boolean" == typeof(error.bubbles)) ? String(error.bubbles) : "",
message: error.message,
line_no: (error.lineno || ""),
col_no: (error.colno || ""),
filename: (error.filename || ""),
stack: (error.stack || ""),
type: (error.type || ""),
page: {
title: document.title,
host: document.location.host,
href: document.location.href,
path: document.location.pathname,
protocol: document.location.protocol.replace(/:/g, ""),
query: document.location.search
},
visitor: {
ip_address: "${keen.ip}",
user_agent: "${keen.user_agent}",
referrer: document.referrer,
},
keen: {
timestamp: new Date().toISOString(),
addons: [
{ name:"keen:ip_to_geo", input: { ip:"visitor.ip_address" }, output:"visitor.geo" },
{ name:"keen:ua_parser", input: { ua_string:"visitor.user_agent" }, output:"visitor.tech" }
]
}
};
console.log('report', report);
logger.addEvent("js_error", report)
return;
}
}('Keen', this);
!function(){
var test = a * 0;
}();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment