<h1>ga.js: Track JavaScript, AngularJS and jQuery errors with Google Analytics</h1>

Generate an error:

<!-- BUTTONS -->
<div class="btn-group">

<button class="btn btn-default js-error" type="button">Pure JavaScript</button>

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.13/angular.js"></script>
<button ng-app="loggerApp" ng-controller="loggerController" class="btn btn-default" ng-click="generateAngularError()" type="button">AngularJS</button>
  
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.js"></script>
<button class="btn btn-default jquery-error" type="button">jQuery</button>
<button class="btn btn-default jquery-ajax-error" type="button">jQuery Ajax</button>
  
</div>

<!-- DEVELOPER CONSOLE OUTPUT TO HTML -->
<div class="light-theme">
[[[https://codepen.io/malyw/pen/vExwoK]]]
</div>

<!-- GOOGLE ANALYTICS GA.JS -->
<script>
var _gaq = _gaq || [];
		_gaq.push(['_setAccount', 'UA-53471595-10']);
		_gaq.push(['_trackPageview']);
		(function () {
			var ga = document.createElement('script');
			ga.type = 'text/javascript';
			ga.async = true;
			ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
			var s = document.getElementsByTagName('script')[0];
			s.parentNode.insertBefore(ga, s);
		})();
</script>
/*--- GENERATE ERRORS ---*/
// Generate Pure JS error
document.querySelector('.js-error')
        .addEventListener('click', function () {
            unicorn();// is not defined- triggers an error
        });

// Generate AngularJS error
angular.module('loggerApp', [])
        .controller('loggerController', function ($scope) {
            $scope.generateAngularError = function () {
                angularUnicorn();// is not defined- triggers an error
            };
        });

// Generate jQuery error
$('.jquery-error').on('click', function () {
    $.error("$.error is called");// https://api.jquery.com/jquery.error/
});

// Generate jQuery Ajax error
$('.jquery-ajax-error').on('click', function () {
    $.get('some-not-existed-url');
});

/*--- ERROR HANDLERS ---*/
// Pure JavaScript errors handler
window.addEventListener('error', function (err) {
  console.log('JavaScript Error:');
  console.error({
        message: err.message,
        filename: err.filename,
        line: err.lineno,
        column: err.colno// might not be present
    });
  
  var lineAndColumnInfo = err.colno ? ' line:' + err.lineno +', column:'+ err.colno : ' line:' + e.lineno;
  _gaq.push([
    '_trackEvent',
    'JavaScript Error',
    err.message,
    err.filename + lineAndColumnInfo + ' -> ' +  navigator.userAgent,
    0,
    true
  ]);
});

// AngularJS errors handler
angular.module('loggerApp')
        .config(function ($provide) {
            $provide.decorator("$exceptionHandler", function ($delegate) {
                return function (exception, cause) {
                    $delegate(exception, cause);
                    console.log('AngularJS error:');
                  	console.error({
                        msg: exception.message,
                        stack: exception.stack
                    });
                  	_gaq.push([
								    	'_trackEvent',
							  		  'AngularJS error',
									    exception.message,
                      exception.stack,
                      0,
									 	  true
									  ]);
                };
            });
        });

// jQuery errors handler (jQuery API)
jQuery.error = function (message) {
    console.log('jQuery Error:');
  	console.error(message);
  	_gaq.push([
    	'_trackEvent',
  	  'jQuery Error',
	    message,
      navigator.userAgent,
      0,
	 	  true
	  ]);
}

// jQuery AJAX errors handler (jQuery API)
$(document).ajaxError(function (event, request, settings) {
//        console.log(e, request, settings);
    console.log('jQuery Ajax Error:');
  	console.error({
        url: settings.url,
        result: event.result,
        status: request.status,
        statusText: request.statusText,
        type: settings.type,
        crossDomain: settings.crossDomain,
        dataType: settings.dataType
    });
  	_gaq.push([
    	'_trackEvent',
  	  'jQuery Ajax Error',
	    settings.url,
      JSON.stringify({
        result: event.result,
	     	status: request.status,
  	 	  statusText: request.statusText,
	 	    crossDomain: settings.crossDomain,
  	    dataType: settings.dataType
      }),
      0,
	 	  true
	  ]);
});

External CSS

  1. //codepen.io/malyw/pen/vExwoK.css
  2. //maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css

External JavaScript

  1. //codepen.io/malyw/pen/vExwoK.js