Created
January 19, 2014 06:51
-
-
Save Macil/8501382 to your computer and use it in GitHub Desktop.
Automatically report unhandled javascript exceptions to your server!
This file contains hidden or 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
(function(exports) { | |
function nop() {} | |
// IE doesn't always have console, place a no-op shim for it. | |
if (!window.console) { | |
window.console = {log: nop, info: nop, warn: nop, error: nop}; | |
} | |
// Transforms an Error to a simple object that can be JSONified. | |
function error_to_object(error) { | |
var newError = {message: error.message, url: error.fileName, lineNumber: error.lineNumber}; | |
if (error.constructor && error.constructor.name) | |
newError.type = error.constructor.name; | |
// get anything missed. For some reason error.message doesn't show up in this pass. | |
for (var prop in error) { | |
if (!error.hasOwnProperty(prop)) continue; | |
var newProp; | |
if (prop == "fileName") | |
newProp = "url"; | |
else | |
newProp = prop; | |
newError[newProp] = error[prop]; | |
} | |
return newError; | |
} | |
exports.error_to_object = error_to_object; | |
var max_retry_time = 5*60*1000; | |
var logger_url = '/logger.php'; | |
var no_send_before = 0; | |
var no_send_delay = 10; | |
var send_queued = 0; | |
var send_max_queued = 7; | |
function send_error(error, retry_time) { | |
if (typeof error === "string") | |
error = {message: error}; | |
else if (error instanceof Error) | |
error = error_to_object(error); | |
if (!error.hasOwnProperty("message")) { | |
console.error("send_error called without error.message", error); | |
return; | |
} | |
error.pageurl = document.location.href; | |
var errorString = JSON.stringify(error); | |
var now = (new Date()).getTime(); | |
if (now < no_send_before) { | |
if (send_queued < send_max_queued) { | |
send_queued++; | |
setTimeout(function() { | |
send_queued--; | |
send_error(error, retry_time); | |
}, no_send_before-now+10); | |
} | |
return; | |
} | |
if (!retry_time) | |
retry_time = 3*1000; | |
else if (retry_time > max_retry_time) | |
retry_time = max_retry_time; | |
no_send_before = now + no_send_delay; | |
no_send_delay *= 2; | |
if (no_send_delay > max_retry_time) | |
no_send_delay = max_retry_time; | |
$.ajax({ | |
url: logger_url, | |
cache: false, | |
data: {type: "error", data: errorString}, | |
type: 'POST', | |
success: function(data) { | |
console.log("sent javascript error report to server for review"); | |
}, | |
error: function(jqXHR, textStatus, errorThrown) { | |
if (textStatus == "timeout") { | |
console.log("timeout while trying to send error report, retrying soon"); | |
setTimeout(function() { | |
send_error(error, retry_time*2); | |
}, retry_time); | |
} else { | |
console.error("could not send error report. textStatus: "+textStatus+", errorThrown: "+errorThrown); | |
} | |
} | |
}); | |
} | |
exports.send_error = send_error; | |
var old_onerror = window.onerror; | |
window.onerror = function(errorMsg, url, lineNumber, column, errorObj) { | |
try { | |
if (errorObj !== undefined) { | |
send_error(errorObj); | |
} else { | |
var error = {message: errorMsg, url: url, lineNumber: lineNumber, column: column, caughtBy: "window.onerror"}; | |
send_error(error); | |
} | |
if (old_onerror) | |
old_onerror.apply(this, arguments); | |
} catch(e) { | |
// Important. If we have an error in the automatic error reporter, | |
// we need to make sure we don't get in an infinite loop of trying | |
// to report it, triggering it again, and trying to report it again. | |
try { | |
send_error(e); | |
} catch(e) {} | |
} | |
return false; | |
}; | |
})(window.reporter||(window.reporter={})); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hi,
I tried your script. The idea is great, but unfortunately the script itself raises some errors:
{"message":"Converting circular structure to JSON","type":"circular_structure","stack":"TypeError: Converting circular structure to JSON\n at Object.stringify (native)\n at send_error (.../reporter.js:11:59)\n
User-Agent: Mozilla/5.0 (Linux; U; Android 2.3.6; es-es; GT-I9070 Build/GINGERBREAD) App
leWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1
{"message":"Cannot call method 'hasOwnProperty' of null","type":"TypeError", ... }
User-Agent: Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.107 Safari/537.36