23

对于错误报告,我想在我拥有的每个函数的代码周围插入一个 try-catch 包装器。

所以基本上我想更换

function foo(arg){
   bar();
}

...和...

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

有没有办法将这种通用的 try-catch 应用到所有函数而无需手动编辑所有函数?例如通过修改 Function 对象的原型?

编辑

为什么我想尝试捕获我的所有功能:我正在构建一个 HTML5 应用程序,并在 iOS 和 Android 上发布。我可以从我当前的基本 javascript 错误报告中看出,即使该应用程序在我自己的设备上运行良好,但在其他一些设备上确实会发生错误。

我的目标是双重的:每当某人的设备上发生 javascript 错误时......

  1. 我想通知用户该应用程序可能无法完美运行
  2. 我想大致知道错误发生在哪里,所以我知道在哪里寻找问题
4

6 回答 6

22

这并不简单,因为无法找到到处定义的所有 JavaScript 函数。例如,任何此类方法都可能会错过在运行时定义的回调函数。

您也可能不想包装所有函数,因为这将包括浏览器函数和您当然不想包装的 JavaScript 库中的函数。

更好的方法可能是定义一个包装另一个函数的函数:

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

现在您可以使用此功能来装饰您想要的任何东西。如果使用名称空间,包装将变得更加简单:

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

只需将所有函数包装在一个特殊的命名空间中,然后遍历命名空间:

$.each( NS, function(i,n) {
    var p = NS[i];
    if( typeof p === 'function' ) {
        NS[i] = tcWrapper(p);
    }
} );
于 2012-08-02T09:45:25.367 回答
6

我没有足够的声誉来评论接受的答案。

return在 the 之前添加了一个f.apply来传递返回值。

var tcWrapper = function(f) {
    return function() {
        try {
            return f.apply(this, arguments);
        } catch(e) {
            customErrorHandler(e)
        }
    }
}
于 2020-05-14T18:07:34.847 回答
1

好的,我似乎在这里找到了它:http ://www.nczonline.net/blog/2009/04/28/javascript-error-handling-anti-pattern/

基本上,所有函数都被 try-catch 包装器替换,其中包含 try 部分中的原始函数。

于 2012-07-31T14:11:47.907 回答
1

我需要加强一些代码,所以我编写了一个名为的函数fortify并将其放入 NPM 模块中。这是一项正在进行的工作,但它应该有所帮助。

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

奖励:它适用于异步函数。欢迎反馈

于 2017-12-01T02:44:06.837 回答
0

给定的答案已经很好用了,只是想用闭包分享一个新的答案。

定义包装器

const tryCatchWrapper = (executable) => async (...args) => {
    try {
        const result = await executable(...args);
        return result;
    } catch (error) {
        // use any custom handler here
       error.message = `[${executable.name}] - ${error.message}`;
       error.data = {...error.data, input_args: args}
       throw error;
    }
}

没有 try-catch 包装器的函数

const myFunction = async (x, y) => {
    const sum = x + y;
    if (sum > 10) throw new Error(`sum > 10 custom error`)
    return sum;
}

如何使用它

try {
    const wrapperFunction = trycatchWrapper3(myFunction2);
    const output = await wrapperFunction(2, 93)
    console.log(output)
} catch (error) {
    console.error(error)
}

结尾

于 2021-11-16T14:42:48.923 回答
-3

我想知道(这纯粹是猜测,所以不确定这是否可行)你可以做这样的事情:

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

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

同样,这纯粹是猜测,我还没有测试过,但如果可能的话,我认为关键在于eval语句。

于 2012-07-31T14:13:10.800 回答