Skip to content

Instantly share code, notes, and snippets.

@ndbroadbent
Last active April 29, 2016 02:35
Show Gist options
  • Save ndbroadbent/5097601 to your computer and use it in GitHub Desktop.
Save ndbroadbent/5097601 to your computer and use it in GitHub Desktop.
Wrap jQuery events and callbacks with try...catch blocks. Original code from: https://github.com/airbrake/airbrake-js/blob/master/src/notifier.js#L173
/*
* Add hook for jQuery.fn.on function, to manualy call window.Airbrake.captureException() method
* for every exception occurred.
*
* Let function 'f' be binded as an event handler:
*
* $(window).on 'click', f
*
* If an exception is occurred inside f's body, it will be catched here
* and forwarded to captureException method.
*
* processjQueryEventHandlerWrapping is called every time window.Airbrake.setTrackJQ method is used,
* if it switches previously setted value.
*/
processjQueryEventHandlerWrapping: function () {
// Skip jQuery wrapping if IE version is 9 or lower
if (ie_version && ie_version <= 9) { return false; }
if (Config.options.trackJQ === true) {
Config.jQuery_fn_on_original = Config.jQuery_fn_on_original || jQuery.fn.on;
Config.jQuery_fn_ready_original = Config.jQuery_fn_ready_original || jQuery.fn.ready;
var wrapHandler = function (fnOriginHandler) {
return function() {
try {
return fnOriginHandler.apply(this, arguments);
} catch (e) {
Global.captureException(e);
}
};
};
jQuery.fn.on = function () {
var args = Array.prototype.slice.call(arguments),
fnArgIdx = 4;
// Search index of function argument
while((--fnArgIdx > -1) && (typeof args[fnArgIdx] !== 'function'));
// If the function is not found, then subscribe original event handler function
if (fnArgIdx === -1) {
return Config.jQuery_fn_on_original.apply(this, arguments);
}
// If the function is found, then subscribe wrapped event handler function
args[fnArgIdx] = wrapHandler(args[fnArgIdx]);
// Call original jQuery.fn.on, with the same list of arguments, but
// a function replaced with a proxy.
return Config.jQuery_fn_on_original.apply(this, args);
};
jQuery.fn.ready = function (handler) {
// Call original jQuery.fn.ready, with the proxied handler.
return Config.jQuery_fn_ready_original.call(this, wrapHandler(handler));
};
// Set up ajax prefilters once, using jQuery.Callbacks.
// This lets us control a proxied callbacks list, so we can
// clear the callback on tear down, and re-add it on setup.
if (!Config.jQuery_ajax_prefilters) {
Config.jQuery_ajax_prefilters = jQuery.Callbacks();
jQuery.ajaxPrefilter(Config.jQuery_ajax_prefilters.fire);
}
// Set up prefilter that wraps ajax callbacks with try...catch blocks.
Config.jQuery_ajax_prefilters.add(function(options) {
var originalCallback, callbacks = ['success', 'error', 'complete'];
for (var i=0; i<callbacks.length; i++) {
if (options[callbacks[i]]) {
options[callbacks[i]] = wrapHandler(options[callbacks[i]]);
}
}
});
} else {
// If Config.options.trackJQ is set to false,
// recover original jQuery.fn functions
if (typeof Config.jQuery_fn_on_original === 'function') {
jQuery.fn.on = Config.jQuery_fn_on_original;
jQuery.fn.ready = Config.jQuery_fn_ready_original;
}
// Clear our ajax callback.
// jQuery.ajaxPrefilter will still be registered, but will now be shooting blanks.
Config.jQuery_ajax_prefilters.empty();
}
},
@mukeshshukla
Copy link

Is there any working example ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment