skip to content

JavaScript: Using XMLHttpRequest to log JavaScript errors

1 Tweet1 Share

If you've read the related article Recording Outbound Links using Ajax you'll be familiar with the concept of using Ajax to record user actions. This article goes a step further letting you log any JavaScript errors that occur on your site to a text file that you can later view or download.

This can be very handy as many JavaScript errors are user-, browser- or platform-specific and it's not always possible to test a site yourself using all the different combinations.

Defining a Custom Error Handler

The first step is to override or redirect the built in error handler window.onerror with our own function. This is a lot simpler than it sounds:

<script type="text/javascript" src="ajaxrequest.js"></script> <script type="text/javascript"> window.onerror = function(msg, url, line) { if(encodeURIComponent) { var req = new AjaxRequest(); var params = "msg=" + encodeURIComponent(msg) + '&url=' + encodeURIComponent(url) + "&line=" + line; req.setMethod("POST"); return req.loadXMLDoc("/logerror.php", params); } return false; } </script>

One point to note is the return value of the window.onerror function. If you return a value of true then only your function will be called and no message will be presented in the browser. If you instead return a value of false, your error handler will be called and then the browser will respond to the error in it's own way.

The function as presented will either make a successful call to the server-side script (see below) or let the browser display the error to the user as it sees fit. That way someone is always notified of the error.

The best place for this code is in the HEAD of your HTML document or in an included JavaScript file.

Logging errors to a text file

Here we see how a PHP script can be used as the target of the Ajax request in order to record the details of the error:

<?PHP include "class.xmlresponse.php"; if($_POST && isset($_POST['msg']) && isset($_POST['url']) && isset($_POST['line'])) { $msg = $_POST['msg']; $url = $_POST['url']; $line = $_POST['line']; if($fp = fopen("{$_SERVER['DOCUMENT_ROOT']}/onerror.log", "a")) { $logline = "[{$_SERVER['REMOTE_ADDR']}]: $msg in $url on line $line"; fwrite($fp, date("M d H:i:s") . " $logline\n"); fclose($fp); } } $xml = new xmlResponse(); $xml->start(); $xml->end(); ?>

Note: save this script as /logerror.php for the whole example to work.

When it receives a POST request with values for msg, url and line then a line containing that information is added to the file onerror.log. The XML header and empty response tag are necessary only to prevent a JavaScript error in the processReqChange - very important in this case as you don't want to create an infinite loop.

The onerror.log file needs to be writable by the webserver. The best way to enable this is to first touch the file so that it exists, then chgrp the file to the webserver user and finally chmod 664 to make it writable.

Unfortunately the Safari and Opera web browsers no longer support the setting of an onerrer event handler, so this script is less useful than it might have been.

Possible additions to the script

If you're going to use this on a live site then you might want to consider:

The code presented here works in Internet Explorer (Win) and Firefox, but not so well in Safari which seems to have it's own way of handling errors. Some Mozilla browsers also don't pass a value for url to the error handling function.

For more inclusive solutions there are some links posted in the Feedback section below.


< JavaScript

Send a message to The Art of Web:

used only for us to reply, and to display your gravatar.

CAPTCHA refresh

<- copy the digits from the image into this box

press <Esc> or click outside this box to close

User Comments

Post your comment or question

31 October, 2013

A similar client side / server side open source solution for ASP.NET or MVC is JSNLog (

This is a small (1.5kb) but feature rich JavaScript logging library plus a server side dll that receives your client side log messages and passes them on to your server side logging library (NLog, etc.) for logging.

It also let you configure loggers in your web.config, so there is no need to change your code to switch on a logger.

27 May, 2013

Nice article!

We recently launched . It takes care of your browser and mobile devices errors. It's also possible to use it in backend and log the exceptons coming from a NodeJS app.
Worth to give it a try.

13 November, 2011

Great stuff, people should be just as vigilant about logging javascript-errors, as they are about logging php/dotNet/Java errors on their backend. JavaScript errors can be just as bad as a website that is down.

There is a drawback the the method described here using onerror. Errors are not logged on iPhones, iPads, Safari and some other browsers.
If you wan to log on those browsers, you need to insert try catch around all eventhandlers and xhr-requests too. This will also give you a chance to get more information about the error.
We're a startup. We've solved a lot of this problem, while still having a solution that simply installs by copying a script to your page (Like Google Analytics)

Currently we are in private beta (free).

23 September, 2011

we've put together a free, open source version that includes the javascript client side stuff and also a sample AppEngine project to receive error logs and report them back to the developer.

would love thoughts, feedback and maybe some improvements over at (which links through to the GitHub repository as well).

Very nice

22 July, 2008

Thanks for the function, a use them to build a prototype version:

function js_err_logger(msg, url, line)
if(encodeURIComponent) {
var params = 'msg=' + encodeURIComponent(msg) + '&url=' + encodeURIComponent(url) + '&line=' + line;
var uri = '/index.php?opcao=default&tarefa=js_err_logger';
var opt= { method:'post', postBody:params, onSuccess:function(r) { if(debug=='1') alert(r.responseText); }, on404:function(t) { alert(t.statusText)}, onFailure:function(t) { alert(t.statusText) }, asynchronous:true };
return new Ajax.Request(uri,opt);
return false;

window.onerror = js_err_logger;