Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Wrap all methods of existing javascript object with try catch

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.

like image 536
Rana Avatar asked Sep 26 '22 21:09

Rana


1 Answers

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.
       }
    };  
}
like image 135
Daniel Schaffer Avatar answered Oct 11 '22 06:10

Daniel Schaffer