Monkey-patching Jasmine's it() function to log errors The introduction of async native support in Jasmine doesn't log the errors (i.e., specific line number where the error occurs) to the console. So, to get around this behavior and to make the errors appears in the console, I came up with this following solution to patch Jasmine.

I have the following function which I implemented to monkey patch the Jasmine. And I would like to reuse the same function for other functions like beforeEach, beforeAll and so on..

     function patchJasmineForAsyncError(method: string) {
        let oldFn = window[method];
        if (method === 'it' || method === 'fit') {
            window[method] = function (desc: string, fn: Function) {
                    oldFn(description, (done) =&gt; {
                    let p = fn();
                    if (p instanceof Promise) {
                        p.then(() =&gt; done()).catch(e =&gt; {
                            console.error(e);
                            done.fail(e);
                        });
                    }
                    });
            }
        } else {
            window[method] = function (axn: Function) {
                oldFn((done) =&gt; {
                    let p = axn();
                    if (p instanceof Promise) {
                        p.then(() =&gt; done()).catch(e =&gt; {
                            console.error(e);
                            done.fail(e);
                        });
                    }
                });
            }
        }
} 


As you can see the second part of the function (the else block) has quite a lot of duplication. I was wondering if there is an elegant way to minimize this and implement the function. 

Note: the it and fit functions have two arguments desc and fn.. but the beforeAll, beforeEach.. etc have only one argument axn.
Just factor it out into a closure

function patchJasmineForAsyncError(method: string) {
    let oldFn = window[method];
    function create_logger(fn: Function) {
        return (done) =&gt; {
            let p = fn();
            if (p instanceof Promise) {
                p.then(done).catch(e =&gt; {
                    console.error(e);
                    done.fail(e);
                });
            }
        }
    }

    if (method === 'it' || method === 'fit') {
        window[method] = function(desc: string, fn: Function) {
            oldFn(desc, create_logger(fn));
        }
    } else {
        window[method] = function (axn: Function) {
            oldFn(create_logger(axn));
        }
    }
} 


We can clean this up a bit more by getting rid of some magic. I also got rid of the () =&gt; done() because that's the same as done.

function patchJasmineForAsyncError(method: string) {
    let oldFn = window[method];
    function create_logger(fn: Function) {
        return (done) =&gt; {
            let p = fn();
            if (p instanceof Promise) {
                p.then(done).catch(e =&gt; {
                    console.error(e);
                    done.fail(e);
                });
            }
        }
    }

    let allowed_methods = ['it', 'fit'];
    if (allowed_methods.includes(method)) {
        window[method] = function(desc: string, fn: Function) {
            oldFn(desc, create_logger(fn));
        }
    } else {
        window[method] = function (axn: Function) {
            oldFn(create_logger(axn));
        }
    }
} 


We can also reduce some of the duplication in assigning to window[method] if we're okay with adding a slight slow-down to the function, which should be fine.

function patchJasmineForAsyncError(method: string) {
    let oldFn = window[method];
    function create_logger(fn: Function) {
        return (done) =&gt; {
            let p = fn();
            if (p instanceof Promise) {
                p.then(done)
                 .catch(e =&gt; {
                    console.error(e);
                    done.fail(e);
                });
            }
        }
    }
    let allowed_methods = ['it', 'fit'];
    window[method] = function() {
        if (allowed_methods.includes(method)) {
            oldFn(arguments[0], create_logger(arguments[1]));
        } else {
            oldFn(create_logger(arguments[0]));
        }
    }
}