有没有办法在Javascript中为每个函数添加try-catch?

Wyt*_*tze 14 javascript error-handling prototype try-catch

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

所以基本上我想替换

function foo(arg){
   bar();
}
Run Code Online (Sandbox Code Playgroud)

...与...

function foo(arg){
    try {
        bar() 
    }
    catch(e){
        customErrorHandler(e)
    }
}
Run Code Online (Sandbox Code Playgroud)

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

编辑

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

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

  1. 我想通知用户该应用可能无法正常运行
  2. 我想知道错误发生的大致位置,所以我知道在哪里寻找问题

Aar*_*lla 12

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

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

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

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

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

var NS = { f: function() {  } }
Run Code Online (Sandbox Code Playgroud)

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

$.each( NS, function(i,n) {
    var p = NS[i];
    if( typeof p === 'function' ) {
        NS[i] = tcWrapper(p);
    }
} );
Run Code Online (Sandbox Code Playgroud)

  • @nus:我不明白你的意思。我只是传递“这个”,但也许我做错了?也许您的信息太复杂,无法发表评论。在另一个答案中向我们展示代码和原因怎么样? (2认同)

Ful*_*ang 6

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

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

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


Jas*_*ssi 6

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

定义包装器

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

您的函数没有 try-catch 包装器

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

如何使用它

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

结尾