To validate tracking of Exceptions, use the following Array in your Jasmine expectations:
['send', 'exception', { ─────────────────> 1&2. (Standard Google Analytics parameters)
'exDescription': 'DatabaseError', ────> 3. Exception Description
'exFatal': false, ────────────────────> 4. Indicates whether the exception was fatal
'appName', 'Demo_Application', ───────> 5. Application Name
'appVersion', '1.0' ──────────────────> 6. Application Version Number
}]
Using direct ga()
calls, checking proper tracking of Exceptions could be done in the following manner:
describe('The Google Analytics "Exception" tracking', function () {
beforeEach(function () {
// Load the page to test:
browser.get('index.html');
// Register the Google Analytics Event Data Interceptor:
browser.driver.registerGoogleAnalyticsEventDataInterceptor();
});
it('should register an Exception when causing an application crash', function (done) {
// Get the "LastEvent" object back from the browser:
browser.driver.executeScript(function () {
return window.GAWebTester.getLastEvent();
})
.then(
// Validate the content of the "LastData" object:
function successCallback (LastData) {
expect( LastData ).toEqual( ['send', 'exception', {
'exDescription': 'DatabaseError',
'exFatal': false,
'appName': 'Demo_Application',
'appVersion': '1.0'
}] );
},
// If there was an error getting back the "LastData" object from the browser, fail the test:
function errorCallback (error) {
fail('Should not have received Error: ' + JSON.stringify(error));
}
)
.then(done);
});
});
To manually simulate an Error in the browser, the following code will send a DatabaseError
Exception:
/**
* Trigger an Exception in the Browser by throwing an Error then catching
* it with a "ga()" call.
*
* @return {void}
*/
function triggerGoogleAnalyticsException () {
try {
throw new Error('DatabaseError.');
} catch (err) {
// Send the exception to Google Analytics:
ga('send', 'exception', {
'exDescription': err.message,
'exFatal': false,
'appName': 'Demo_Application',
'appVersion': '1.0'
});
}
}
// Trigger a "crash" in the browser:
triggerGoogleAnalyticsException();
Few people know about this, but the free version of Google Analytics supports exception logging. It might be caused by the fact that Google Analytics does not provide any built-in Report surfacing that information. Fortunately, that does not prevent you from making your own.
First, you will need to either:
You can customize a few things:
appName
(string): Name of the application you are trackingappVersion
(string): Version number and/or deployment date of the applicationexFatal
(boolean): “true” or “false”, depending on the Type of Error receivedYou can test that the everything is properly set up by opening your browser’s developer console and typing throw new Error('Crash!')
, then checking your Custom Report a few minutes later to make sure your Error is logged.
For the complete walkthrough of how to set it up, and a free Error Reporting Dashboard, see the full post on philippesawicki.com.
/**!
* Send JavaScript error information to Google Analytics.
*
* @param {Window} window A reference to the "window".
* @param {Object|undefined} options An object containing optional "applicationName" and
* "applicationVersion" strings.
* @return {void}
* @author Philippe Sawicki (https://github.com/philsawicki)
* @copyright Copyright 2015 Philippe Sawicki (http://philippesawicki.com)
*/
(function (window, options) {
// Retain a reference to the previous global error handler, in case it has been set:
var originalWindowErrorCallback = window.onerror;
/**
* Log any script error to Google Analytics.
*
* Third-party scripts without CORS will only provide "Script Error." as an error message.
*
* @param {String} errorMessage Error message.
* @param {String} url URL where error was raised.
* @param {Number} lineNumber Line number where error was raised.
* @param {Number|undefined} columnNumber Column number for the line where the error occurred.
* @param {Object|undefined} errorObject Error Object.
* @return {Boolean} When the function returns true, this prevents the
* firing of the default event handler.
*/
window.onerror = function customErrorHandler (errorMessage, url, lineNumber, columnNumber, errorObject) {
// Send error details to Google Analytics, if the library is already available:
if (typeof ga === 'function') {
// In case the "errorObject" is available, use its data, else fallback
// on the default "errorMessage" provided:
var exceptionDescription = errorMessage;
if (typeof errorObject !== 'undefined' && typeof errorObject.message !== 'undefined') {
exceptionDescription = errorObject.message;
}
// Format the message to log to Analytics (might also use "errorObject.stack" if defined):
exceptionDescription += ' @ ' + url + ':' + lineNumber + ':' + columnNumber;
// Data Object to send to Google Analytics:
var exOptions = {
exDescription: exceptionDescription,
exFatal: false // Some Error types might be considered as fatal.
};
// Format additional Data Object Properties, if any option given:
if (typeof options !== 'undefined') {
if (typeof options.applicationName !== 'undefined') {
exOptions.appName = options.applicationName;
}
if (typeof options.applicationVersion !== 'undefined') {
exOptions.appVersion = options.applicationVersion;
}
}
// Send Data Object to Google Analytics:
ga('send', 'exception', exOptions);
}
// If the previous "window.onerror" callback can be called, pass it the data:
if (typeof originalWindowErrorCallback === 'function') {
return originalWindowErrorCallback(errorMessage, url, lineNumber, columnNumber, errorObject);
}
// Otherwise, let the default handler run:
return false;
};
})(window, {
applicationName: 'Application_Name', // Optional "Application Name" parameter (set your own).
applicationVersion: '1.0' // Optional "Application Version" parameter (set your own).
});
// Generate an error, for demonstration purposes:
//throw new Error('Crash!');