Is there a way to add try-catch to every function

2019-03-25 10:47发布

For error reporting, I would like to insert a try-catch wrapper around the code of every function I have.

So basically I want to replace

function foo(arg){
   bar();
}

...with...

function foo(arg){
    try {
        bar() 
    }
    catch(e){
        customErrorHandler(e)
    }
}

Is there a way to apply this generic try-catch thing to all functions without manually editing all of them? For example by modifying the prototype of the Function object?

EDIT

Why I want to try-catch all my functions: I am building an HTML5 app that I'm publishing on iOS and Android. I can tell from my current rudimentary javascript error reporting that even though the app runs nicely on my own device, errors do occur on some other devices.

My objective is twofold: whenever a javascript error occurs on someone's device...

  1. I want to notify the user that the app may not function perfectly
  2. I want to know roughly where the error occurred, so I know where to look for the problem

4条回答
我想做一个坏孩纸
2楼-- · 2019-03-25 11:09

Okay, I seem to have found it here: http://www.nczonline.net/blog/2009/04/28/javascript-error-handling-anti-pattern/

Basically, all functions are replaced by a try-catch wrapper with the original function in the try part.

查看更多
够拽才男人
3楼-- · 2019-03-25 11:09

This isn't simple since there is no way to find all JavaScript function defined everywhere. For example, any such approach would probably miss callback functions which are defined at runtime.

You also probably don't want to wrap all functions because that would include browser functions and functions from JavaScript libraries that you certainly don't want to wrap.

A much better approach is probably to define a function which wraps another function:

var tcWrapper = function(f) {
    return function() {
        try {
            f.apply(this, arguments);
        } catch(e) {
            customErrorHandler(e)
        }
    }
}

Now you can use this function to decorate anything that you want. Wrapping will become more simple if you use name spaces:

var NS = { f: function() {  } }

Just put all functions to wrap in a special namespace and then iterate over the namespace:

$.each( NS, function(i,n) {
    var p = NS[i];
    if( typeof p === 'function' ) {
        NS[i] = tcWrapper(p);
    }
} );
查看更多
叼着烟拽天下
4楼-- · 2019-03-25 11:12

I wonder (this is pure speculation, so not sure if this would work) you could do something like this:

function callTryCatch(functionSignature) {
    try {
        eval(functionSignature);
    } catch (e) {
        customErrorHandler(e);
    }
}

function entryPoint() {
    callTryCatch(function() {
        // do function logic
    });
}

Again, this is pure speculation and I haven't tested but if it's even possible I think the key lies in the eval statement.

查看更多
做个烂人
5楼-- · 2019-03-25 11:32

I needed to go fortify some code, so I wrote a function called fortify and put it in an NPM module. It's a work in progress, but it should help.

https://github.com/infinitered/over-armour

Bonus: it works with async functions. Feedback welcome

查看更多
登录 后发表回答