Skip to content

Instantly share code, notes, and snippets.

@dennissterzenbach
Last active June 13, 2018 20:28
Show Gist options
  • Save dennissterzenbach/ec63019cac6b415a2c6e9b3937e7ab83 to your computer and use it in GitHub Desktop.
Save dennissterzenbach/ec63019cac6b415a2c6e9b3937e7ab83 to your computer and use it in GitHub Desktop.
This higher order function logic wraps a given function with error handling to make it exception fail safe
// create a function which produces an exception when called
function failing() {
throw new SyntaxError('ERROR MAN!');
}
// create new handler instance and push it one error handler which is called when exception occurs after calling the "function failing":
var hdl = new ErrorHandler([
function handleIt1(yo) { console.log('ERROR', yo); }
]);
var x = hdl.makeExceptionFailSafe(failing);
// call the "fail safe" function
x();
/*
This results in the following:
ERROR SyntaxError: ERROR MAN!
at ErrorHandler.failing (...:xxxx:yyyy)
at ErrorHandler.exceptionSafeCommands (...:xxxx:yyyy)
at ...:xxxx:yyyy
and the return value of x(); is the object with the exception as payload and the flag set accordingly:
Object {payload: SyntaxError: ERROR MAN! at ErrorHandler.failing..., isException: true}
*/
/**
* Error Handler dummy
* used to provide a higher order function which allows exception fail safe calling
* and provides some error handling along with.
*
* @author Dennis Sterzenbach <dennis.sterzenbach@gmail.com>
*/
function ErrorHandler(errorHandlerFunctions) {
this.handlers = [];
// add all entries from param to internal handlers list keeping identity
if (errorHandlerFunctions && errorHandlerFunctions.length) {
Array.prototype.push.apply(this.handlers, errorHandlerFunctions);
}
}
/**
* @description
* This method is a higher order function which receives a function and will
* return a new function which internally wrapped exception handling around the
* given code.
*
* That way the caller does not have to worry about handling exceptions
* correctly.
*
* The return value of the generated function will provide the caller an
* object with the boolean status `isException` and `payload` containing
* either the return value from the wrapped function or the exception
* that occured.
*
* @param {function} givenFn some function to wrap with exception handling to make it safe
*
* @example
* <pre>
* var fnWrappedWithErrorHandling = ErrorHandler.makeExceptionFailSafe(function(params) {
* // call This
* // call something which might produce errors
* });
*
* // execute the function and let ErrorHandler do its job if necessary
* var returnedObject = fnWrappedWithErrorHandling(theParameters);
*
* // returnObject: { payload: 'the return value', isException: false }
* </pre>
*/
ErrorHandler.prototype.makeExceptionFailSafe = function makeExceptionFailSafe(givenFn) {
var errorReturnValue = {
payload: undefined,
isException: false
};
if (!givenFn || !(givenFn instanceof Function) || !(typeof givenFn === 'function') || !/function .*\(\)/.test(givenFn.toString())) {
return null;
}
return function exceptionSafeCommands() {
try {
// call original function and store its return value as payload
// NOTE the "this" used when calling the function!
errorReturnValue.payload = givenFn.apply(this, arguments);
} catch (exception) {
// handle exception
this.handleException(exception);
// return to the caller
errorReturnValue.payload = exception;
errorReturnValue.isException = true;
}
return errorReturnValue;
}.bind(this);
};
ErrorHandler.prototype.handleException = function handleException(exception) {
// call each handler once for the given exception
this.handlers.forEach(function(handler) {
handler(exception);
});
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment