Wrap all methods of existing javascript object with try catch

- 1 answer

Ad

Is there a descent way to wrap all methods in an existing javascript object(for example third party library) with try catch so that I can process the exeception errors? Sure, I will expose the methods under a new interface.

Here is what I have in mind for now:(consider it as pseudocode)

var MyInterface = {};
for (var property in thirdPartyLib) {
  if ((typeof thirdPartyLib[property]) === 'function'){
    MyInterfac[property] = function(){
      try {
        thirdPartyLib[property](arguments)
      }
      catch(err){
         //do my custom processing
      }
    }
  }   
}

//developer use MyInterface object

Just wondering, any better approach or any flaw with my above idea? Thanks.

Ad

Answer

Ad

Almost! The only issue is that you aren't passing the arguments correctly. arguments is a pseudo-array object that contains all of the arguments passed into the function call. What will end up happening with your code as-is, is that the real function would get called with a single object, rather than the individual arguments you received in your wrapper function.

What you can also do is use a closure to just do an in-place wrapping so you don't need to worry about using a different object.

function safeWrap(service, fn) {
    var ogFn = service[fn];
    service[fn] = function () {
       try { return ogFn.apply(service, arguments); }
       catch (err) {
           // doh.
       }
    };  
}

function wrapObj(service) {    
    for (var fn in thirdPartyLib) {
        var type = typeof(thirdPartyLib[fn]);
        if (type === 'function') {
            safeWrap(thirdPartyLib, fn);
        } else if (type === 'object') {
            wrapObj(thirdPartyLib[fn]);
        }
    }
}

wrapObj(thirdPartyLib);

Edited to make the wrapping recursive, per @RobG's suggestion

If performance is an issue, you can manually pass the arguments to avoid the perf hit of using Function.apply:

function safeWrap(service, fn) {
    var ogFn = service[fn];
    service[fn] = function (a, b, c, d, e, f, g, h, i, j, k, l) {
       if (arguments.length > 12) {
           console.error('Time to add %s more args!', arguments.length - 12);
       }
       try { return ogFn.call(service, a, b, c, d, e, f, g, h, i, j, k, l); }
       catch (err) {
           // doh.
       }
    };  
}
Ad
source: stackoverflow.com
Ad