JSFiddle - React, Tailwind, and code Playground
JavaScript
var mylib = (function() {
// Custom error type used when throwing internally
var ManagedError = function(message) {
Error.prototype.constructor.apply(this, arguments);
this.message = message;
};
ManagedError.prototype = new Error();
/**
* Wraps a function so that it will never throw and bubble
*/
function unguard(fn) {
return function() {
try {
return fn.apply(this, arguments);
} catch (e) {
// surface the error
console.log(' - bubbling error to window.onerror');
setTimeout(function() {
throw e;
}, 0);
}
};
}
// Helper function for wrapping all functions
function wrap(fn, value) {
// not all 'function's are actually functions!
if (typeof value === 'function' && /^function/.test(value.toString())) {
return fn(value);
} else if (typeof value === 'object' && value !== null) {
for (var key in value) if (value.hasOwnProperty(key)) {
value[key] = wrap(fn, value[key]);
};
}
return value;
}
/**
* Wraps a function so that any error thrown is reported.
* ManagedError's are disregarded and rethrown.
*/
function guard(fn) {
return function() {
// capture the arguments and unguard any functions
var args = Array.prototype.slice.call(arguments).map(wrap.bind(null, unguard));
try {
return wrap(guard, fn.apply(this, args));
} catch (e) {
// If this is a ManagedError, then this is something that we want to
// surface without logging it
if (e instanceof ManagedError) {
console.log(' - Managed error: re-throw', e);
throw e;
}
// log error
...