function wrap( fcn, thisArg ) {
	var ctx;
	if ( !isFunction( fcn ) ) {
		throw new TypeError( format( 'invalid argument. Must provide a function. Value: `%s`.', fcn ) );
	}
	if ( arguments.length > 1 ) {
		ctx = thisArg;
	} else {
		ctx = null;
	}
	return wrapped;

	/**
	* Wrapped function.
	*
	* @private
	* @param {...*} [args] - function arguments
	* @returns {*|Error} returned value or an error object
	*/
	function wrapped() {
		var args;
		var len;
		var i;

		len = arguments.length;
		args = new Array( len );
		for ( i = 0; i < len; i++ ) {
			args[ i ] = arguments[ i ];
		}
		try {
			return fcn.apply( ctx, args );
		} catch ( error ) {
			if ( isError( error ) ) {
				return error;
			}
			// Handle thrown literals...
			if ( typeof error === 'object' ) {
				return new Error( JSON.stringify( error ) );
			}
			return new Error( error.toString() );
		}
	}
}
Wraps a function in a try/catch block.

@param {Function} fcn - function to wrap
@param {*} [thisArg] - function context
@throws {TypeError} must provide a function
@returns {Function} wrapped function

@example
function fcn() {
    throw new Error( 'beep boop' );
}

var f = wrap( fcn );

var out = f();
if ( out instanceof Error ) {
    console.error( out.message );
    // => 'beep boop'
}