// singleton class constructor function Logger() { // fields this.req; // methods this.errorToXML = errorToXML; this.log = log; } // map an error to an XML document function errorToXML(err) { var xml = '' + '' + ' ' + encodeXml(err.name) + '' + ' ' + encodeXml(err.message) + ''; if (err.location) xml += ' ' + encodeXml(err.location) + ''; xml += ''; return xml; } // log method of Logger class function log(err) { // feature sniff if (window.XMLHttpRequest) this.req = new XMLHttpRequest(); else if (window.ActiveXObject) this.req = new ActiveXObject("Microsoft.XMLHTTP"); else return; // throw up our hands in despair // set the method and URI this.req.open("POST", "/Error/JsError.aspx"); // set the request headers. REFERER will be the top-level // URI which may differ from the location of the error if // it occurs in an included .js file this.req.setRequestHeader('REFERER', location.href); this.req.setRequestHeader('content-type', 'text/xml'); // function to be called when the request is complete this.req.onreadystatechange = errorLogged; this.req.send(this.errorToXML(err)); // if the request doesn't complete in 10 seconds, // something is up this.timeout = window.setTimeout("abortLog();", 10000); } // should only be one instance of the logger var logger = new Logger(); // we tried, but if there is a connection error, it is hopeless function abortLog() { logger.req.abort(); alert("Attempt to log the error timed out."); } // called when the state of the request changes function errorLogged() { if (logger.req.readyState != 4) return; window.clearTimeout(logger.timeout); // request completed if (logger.req.status >= 400) alert('Attempt to log the error failed.'); } function trapError(msg, URI, ln) { // wrap our unknown error condition in an object var error = new Error(msg); error.location = URI + ', line: ' + ln; // add custom property logger.log(error); return false; //warnUser(); //return true; // stop the yellow triangle } function warnUser() { alert("An error has occurred while processing this page. Our engineers have been alerted!"); // drastic action location.href = '/path/to/error/page.html'; } function encodeXml(val) { if(val && val.replace) { var retVal = val.replace(/[&]/g, "&"); //MUST be done FIRST! retVal = retVal.replace(/["]/g, """); retVal = retVal.replace(/[']/g, "'"); retVal = retVal.replace(/[<]/g, "<"); retVal = retVal.replace(/[>]/g, ">"); return retVal; } return val; } window.onerror = trapError;