├── README.md ├── index.html ├── js_logger.js └── js_logger.min.js /README.md: -------------------------------------------------------------------------------- 1 | JavaScript error logging 2 | ======================== 3 | 4 | Small tool for logging JavaScript errors via window.onerror event 5 | - No jQuery or other dependencies, except JSON.stringify (IE8+) 6 | - RequireJS support 7 | - Smart detection of DOMContentLoaded/onload event 8 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | JavaScript error logging demo 5 | 6 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /js_logger.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Logging function that will trap javascript errors and report them 3 | * Update track_event_url variable for your needs 4 | * 5 | * @author sap1ens https://github.com/sap1ens/javascript-error-logging (fork from https://github.com/robby1066/javascript-error-logging) 6 | * @version 1.0 7 | * @dependency JSON.stringify() // IE8+ 8 | */ 9 | var js_logger = (function() { 10 | 11 | var track_event_url = 'index.html', 12 | is_loaded = false, // flag to let us know it's safe to log errors. 13 | errors = [], 14 | error_count = 0, 15 | max_errors = 10; // prevent runaway logging for infinite loops 16 | 17 | function logError(msg, url, line) { 18 | // save the errors to an array, this will be emptied out when the page is fully loaded. 19 | if (typeof msg !== "undefined" && error_count < max_errors) { 20 | error_count++; 21 | 22 | // use current URL by default 23 | if(!url) url = location.href; 24 | 25 | var track_error = { 26 | message: msg, 27 | url: url, 28 | line: line, 29 | userAgent: navigator.userAgent, 30 | time: (new Date()).getTime() 31 | }; 32 | 33 | errors.push(track_error); 34 | 35 | if(typeof console !== "undefined") { 36 | console.log("Logger saved: " + msg); 37 | } 38 | 39 | if (is_loaded == true) { 40 | reportErrors(); 41 | } 42 | } 43 | } 44 | 45 | var xmlVersions = [ 46 | "Msxml2.XMLHTTP.6.0", 47 | "MSXML2.XMLHTTP.3.0", 48 | "MSXML2.XMLHTTP", 49 | "Microsoft.XMLHTTP" 50 | ]; 51 | 52 | if(typeof XMLHttpRequest == "undefined") XMLHttpRequest = function() { 53 | for(var i in xmlVersions) { 54 | try { return new ActiveXObject(xmlVersions[i]); } 55 | catch(e) {} 56 | } 57 | }; 58 | 59 | function reportErrors() { 60 | if(errors.length > 0) { 61 | var params = '{"loggedErrors":' + JSON.stringify(errors) + '}'; 62 | 63 | var req = new XMLHttpRequest(); 64 | req.open('POST', track_event_url, true) 65 | req.setRequestHeader("Content-Type", "application/json"); 66 | req.send(params); 67 | 68 | errors = []; 69 | error_count = 0; 70 | } 71 | } 72 | 73 | /** 74 | * RequireJS support 75 | */ 76 | function setRequireJSErrorHandling() { 77 | if(typeof require !== "undefined" && require.onError) { 78 | require.onError = function(msg) { 79 | 80 | // if object 81 | if(msg === Object(msg) && msg.requireType && msg.requireModules) { 82 | msg = "requireType: " + msg.requireType + ", requireModules: " + msg.requireModules; 83 | } 84 | 85 | logError(msg, "", 0); 86 | }; 87 | } 88 | } 89 | 90 | /** 91 | * Cross-browser support of onDOMContentLoaded event 92 | * 93 | * http://javascript.ru/tutorial/events/ondomcontentloaded 94 | */ 95 | function onReady(handler) { 96 | var called = false; 97 | 98 | function ready() { 99 | if (called) return; 100 | called = true; 101 | handler(); 102 | } 103 | 104 | if (document.addEventListener) { 105 | document.addEventListener("DOMContentLoaded", function() { 106 | ready(); 107 | }, false) 108 | } else if (document.attachEvent) { 109 | if (document.documentElement.doScroll && window == window.top) { 110 | function tryScroll() { 111 | if (called) return; 112 | if (!document.body) return; 113 | try { 114 | document.documentElement.doScroll("left"); 115 | ready(); 116 | } catch(e) { 117 | setTimeout(tryScroll, 0); 118 | } 119 | } 120 | tryScroll(); 121 | } 122 | 123 | document.attachEvent("onreadystatechange", function() { 124 | if (document.readyState === "complete") { 125 | ready(); 126 | } 127 | }); 128 | } 129 | 130 | if (window.addEventListener) { 131 | window.addEventListener('load', ready, false); 132 | } else if (window.attachEvent) { 133 | window.attachEvent('onload', ready); 134 | } 135 | } 136 | 137 | return { 138 | init: function() { 139 | var loaded = function() { 140 | setRequireJSErrorHandling(); 141 | 142 | is_loaded = true; 143 | reportErrors(); 144 | }; 145 | 146 | onReady(loaded); 147 | 148 | window.onerror = function(msg, url, line) { 149 | logError(msg, url, line); 150 | 151 | // change to the "true" for suppressing error 152 | return false; 153 | }; 154 | }, 155 | report: function(msg, url, line) { 156 | logError(msg, url, line); 157 | } 158 | }; 159 | })(); 160 | 161 | js_logger.init(); 162 | -------------------------------------------------------------------------------- /js_logger.min.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Logging function that will trap javascript errors and report them 3 | * 4 | * @author sap1ens https://github.com/sap1ens/javascript-error-logging (fork from https://github.com/robby1066/javascript-error-logging) 5 | * @dependency JSON.stringify() // IE8+ 6 | */ 7 | var js_logger=function(){function e(b,a,c){"undefined"!==typeof b&&f