我想捕获抛出的每个未定义函数错误。JavaScript中是否有全局错误处理工具?用例是从flash中捕获未定义的函数调用。


当前回答

我建议你试试Trackjs。

它将错误日志记录作为一种服务。

设置起来非常简单。只需要在每页中添加一行<script>就可以了。这也意味着如果你决定不喜欢它,它将非常简单地删除。

还有其他服务,如Sentry(如果你可以托管自己的服务器,它是开源的),但它不能做Trackjs所做的事情。Trackjs记录用户在浏览器和web服务器之间的交互,这样你就可以实际跟踪导致错误的用户步骤,而不仅仅是文件和行号引用(可能还有堆栈跟踪)。

其他回答

尝试Atatus,它为现代web应用程序提供高级错误跟踪和真实用户监控。

https://www.atatus.com/

让我来解释一下如何获得在所有浏览器中都相当完整的堆栈跟踪。

JavaScript错误处理

现代Chrome和Opera完全支持ErrorEvent和window.onerror的HTML 5草案规范。在这两个浏览器中,你都可以使用window。Onerror,或者正确地绑定到'error'事件:

// Only Chrome & Opera pass the error object.
window.onerror = function (message, file, line, col, error) {
    console.log(message, "from", error.stack);
    // You can send data to your server
    // sendError(data);
};
// Only Chrome & Opera have an error attribute on the event.
window.addEventListener("error", function (e) {
    console.log(e.error.message, "from", e.error.stack);
    // You can send data to your server
    // sendError(data);
})

不幸的是,Firefox、Safari和IE仍然存在,我们也必须支持它们。由于在窗口中无法使用堆栈跟踪。一旦出错,我们就得再做一点工作。

事实证明,要从错误中获得堆栈跟踪,我们唯一能做的就是将所有代码包装在一个try{}catch(e){}块中,然后查看e.stack。我们可以使用一个名为wrap的函数来简化这个过程,该函数接受一个函数并返回一个具有良好错误处理的新函数。

function wrap(func) {
    // Ensure we only wrap the function once.
    if (!func._wrapped) {
        func._wrapped = function () {
            try{
                func.apply(this, arguments);
            } catch(e) {
                console.log(e.message, "from", e.stack);
                // You can send data to your server
                // sendError(data);
                throw e;
            }
        }
    }
    return func._wrapped;
};

这个作品。任何手动包装的函数都有很好的错误处理,但事实证明,在大多数情况下,我们实际上可以自动为您做这件事。

通过改变addEventListener的全局定义,使它自动包装回调,我们可以在大多数代码中自动插入try{}catch(e){}。这让现有代码继续工作,但增加了高质量的异常跟踪。

var addEventListener = window.EventTarget.prototype.addEventListener;
window.EventTarget.prototype.addEventListener = function (event, callback, bubble) {
    addEventListener.call(this, event, wrap(callback), bubble);
}

我们还需要确保removeEventListener继续工作。目前不会,因为addEventListener的参数已经改变。同样,我们只需要在原型对象上修复这个:

var removeEventListener = window.EventTarget.prototype.removeEventListener;
window.EventTarget.prototype.removeEventListener = function (event, callback, bubble) {
    removeEventListener.call(this, event, callback._wrapped || callback, bubble);
}

将错误数据传输到后端

您可以使用图像标签发送错误数据,如下所示

function sendError(data) {
    var img = newImage(),
        src = 'http://yourserver.com/jserror&data=' + encodeURIComponent(JSON.stringify(data));

    img.crossOrigin = 'anonymous';
    img.onload = function success() {
        console.log('success', data);
    };
    img.onerror = img.onabort = function failure() {
        console.error('failure', data);
    };
    img.src = src;
}

免责声明:我是https://www.atatus.com/的web开发人员。

这对你有帮助吗:

<script type="text/javascript">
window.onerror = function() {
    alert("Error caught");
};

xxx();
</script>

我不确定它是如何处理Flash错误的…

更新:它不能在Opera中工作,但我现在正在黑蜻蜓,看看它能得到什么。关于破解蜻蜓的建议来自这个问题:

模拟窗口。onerror在Opera使用javascript

我建议你试试Trackjs。

它将错误日志记录作为一种服务。

设置起来非常简单。只需要在每页中添加一行<script>就可以了。这也意味着如果你决定不喜欢它,它将非常简单地删除。

还有其他服务,如Sentry(如果你可以托管自己的服务器,它是开源的),但它不能做Trackjs所做的事情。Trackjs记录用户在浏览器和web服务器之间的交互,这样你就可以实际跟踪导致错误的用户步骤,而不仅仅是文件和行号引用(可能还有堆栈跟踪)。

复杂的错误处理

如果你的错误处理非常复杂,因此可能会抛出一个错误本身,添加一个标志来表明你是否已经在“errorHandling-Mode”是很有用的。像这样:

var appIsHandlingError = false;

window.onerror = function() {
    if (!appIsHandlingError) {
        appIsHandlingError = true;
        handleError();
    }
};

function handleError() {
    // graceful error handling
    // if successful: appIsHandlingError = false;
}

否则你会发现自己陷入了一个无限循环。

你可以通过给window.onerror赋值函数来监听onerror事件:

 window.onerror = function (msg, url, lineNo, columnNo, error) {
        var string = msg.toLowerCase();
        var substring = "script error";
        if (string.indexOf(substring) > -1){
            alert('Script Error: See Browser Console for Detail');
        } else {
            alert(msg, url, lineNo, columnNo, error);
        }   
      return false; 
  };