Automatically report unhandled javascript exceptions to your server!
(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
This comment has been minimized.
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