Skip to content

Commit

Permalink
Add automatic & manual tracking of JS errors to JavaScript tracker (c…
Browse files Browse the repository at this point in the history
…lose #16)
  • Loading branch information
chuwy committed Nov 2, 2016
1 parent 27ddb42 commit 38f97e4
Show file tree
Hide file tree
Showing 2 changed files with 160 additions and 0 deletions.
131 changes: 131 additions & 0 deletions src/js/errors.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
/*
* JavaScript tracker for Snowplow: tracker.js
*
* Significant portions copyright 2010 Anthon Pang. Remainder copyright
* 2012-2016 Snowplow Analytics Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of Anthon Pang nor Snowplow Analytics Ltd nor the
* names of their contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

var lodash = require('./lib_managed/lodash'),
helpers = require('./lib/helpers'),
object = typeof exports !== 'undefined' ? exports : this,
windowAlias = window;


object.errorManager = function (core) {

/**
* Send error as self-describing event
*
* @param message string Message appeared in console
* @param filename string Source file (not used)
* @param lineno number Line number
* @param colno number Column number (not used)
* @param error Error error object (not present in all browsers)
* @param contexts Array of custom contexts
*/
function track(message, filename, lineno, colno, error, contexts) {
var stack = (error && error.stack) ? error.stack : null;

core.trackSelfDescribingEvent({
schema: 'iglu:com.snowplowanalytics.snowplow/application_error/jsonschema/1-0-0',
data: {
programmingLanguage: "JAVASCRIPT",
message: message,
stackTrace: stack,
lineNumber: lineno
}
}, contexts)
}

/**
* Attach custom contexts using `contextAdder`
*
*
* @param contextsAdder function to get details from internal browser state
* @returns {Array} custom contexts
*/
function sendError(errorEvent, commonContexts, contextsAdder) {
var contexts;
if (lodash.isFunction(contextsAdder)) {
contexts = commonContexts.concat(contextsAdder(errorEvent));
} else {
contexts = commonContexts;
}

track(errorEvent.message, errorEvent.filename, errorEvent.lineno, errorEvent.colno, errorEvent.error, contexts)
}

return {

/**
* Track unhandled exception.
* This method supposed to be used inside try/catch block or with window.onerror
* (contexts won't be attached), but NOT with `addEventListener` - use
* `enableErrorTracker` for this
*
* @param message string Message appeared in console
* @param filename string Source file (not used)
* @param lineno number Line number
* @param colno number Column number (not used)
* @param error Error error object (not present in all browsers)
* @param contexts Array of custom contexts
*/
trackError: track,

/**
* Curried function to enable tracking of unhandled exceptions.
* Listen for `error` event and
*
* @param filter Function ErrorEvent => Bool to check whether error should be tracker
* @param contextsAdder Function ErrorEvent => Array<Context> to add custom contexts with
* internal state based on particular error
*/
enableErrorTracking: function (contexts) {
return function (filter, contextsAdder) {
/**
* Closure callback to filter, contextualize and track unhandled exceptions
*
* @param errorEvent ErrorEvent passed to event listener
*/
function captureError (errorEvent) {
if (lodash.isFunction(filter) && (filter(errorEvent))) {
sendError(errorEvent, contexts, contextsAdder)
} else if (filter == null) {
sendError(errorEvent, contexts, contextsAdder)
}
}

helpers.addEventListener(windowAlias, 'error', captureError, true);
}
}


}
};
29 changes: 29 additions & 0 deletions src/js/tracker.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
sha1 = require('sha1'),
links = require('./links'),
forms = require('./forms'),
errors = require('./errors'),
requestQueue = require('./out_queue'),
coreConstructor = require('snowplow-tracker-core').trackerCore,
uuid = require('uuid'),
Expand Down Expand Up @@ -240,6 +241,9 @@
// Manager for automatic form tracking
formTrackingManager = forms.getFormTrackingManager(core, trackerId, addCommonContexts),

// Manager for tracking unhandled exceptions
errorManager = errors.errorManager(core),

// Manager for local storage queue
outQueueManager = new requestQueue.OutQueueManager(
functionName,
Expand Down Expand Up @@ -2148,6 +2152,31 @@
currency: currency
}
});
},

/**
* Enable tracking of unhandled exceptions with custom contexts
*
* @param filter Function ErrorEvent => Bool to check whether error should be tracker
* @param contextsAdder Function ErrorEvent => Array<Context> to add custom contexts with
* internal state based on particular error
*/
enableErrorTracking: errorManager.enableErrorTracking(addCommonContexts()),

/**
* Track unhandled exception.
* This method supposed to be used inside try/catch block
*
* @param message string Message appeared in console
* @param filename string Source file (not used)
* @param lineno number Line number
* @param colno number Column number (not used)
* @param error Error error object (not present in all browsers)
* @param contexts Array of custom contexts
*/
trackError: function (message, filename, lineno, colno, error, contexts) {
var enrichedContexts = addCommonContexts(contexts);
errorManager.trackError(message, filename, lineno, colno, error, enrichedContexts);
}
};
};
Expand Down

0 comments on commit 38f97e4

Please sign in to comment.