JavaScript异常处理

JavaScript异常处理,javascript,exception,Javascript,Exception,捕获JavaScript中抛出的所有异常的最佳技术是什么 显然,最好的技巧是使用try…catch。但对于异步回调等,这可能会变得棘手 我知道IE和Gecko浏览器支持window.onerror,但Opera和Safari呢 下面是一组测试用例,我想为它们提供一个中央异常处理解决方案: // ErrorHandler-Test1 var test = null; test.arg = 5; // ErrorHandler-Test2 throw (new Error("Hello")); //

捕获JavaScript中抛出的所有异常的最佳技术是什么

显然,最好的技巧是使用try…catch。但对于异步回调等,这可能会变得棘手

我知道IE和Gecko浏览器支持window.onerror,但Opera和Safari呢

下面是一组测试用例,我想为它们提供一个中央异常处理解决方案:

// ErrorHandler-Test1
var test = null;
test.arg = 5;
// ErrorHandler-Test2
throw (new Error("Hello"));
// ErrorHandler-Test3
throw "Hello again";
// ErrorHandler-Test4
throw {
    myMessage: "stuff",
    customProperty: 5,
    anArray: [1, 2, 3]
};
// ErrorHandler-Test5
try {
    var test2 = null;
    test2.arg = 5;
} catch(e) {
    ErrorHandler.handleError(e);
}
// ErrorHandler-Test6
try {
    throw (new Error("Goodbye"));
} catch(e) {
    ErrorHandler.handleError(e);
}
// ErrorHandler-Test7
try {
    throw "Goodbye again";
} catch(e) {
    ErrorHandler.handleError(e);
}
// ErrorHandler-Test8
try {
    throw {
        myMessage: "stuff",
        customProperty: 5,
        anArray: [1, 2, 3]
    };
} catch(e) {
    ErrorHandler.handleError(e);
}
如果您想到任何其他测试用例,请提及它们。其中有几个案例提到了ErrorHandler.handleError方法。这只是使用try…catch时的建议指南。

WebKit(Safari、Chrome等)现在似乎支持
onerror

原始帖子:据我所知,WebKit/Safari不支持
onerror
事件。这真是太可惜了。

如果您使用类似的库来分配所有事件处理程序,那么您可以结合使用
window.onerror
,并将jQuery事件处理程序代码和on ready函数包装为错误处理函数(请参阅:)

  • window.onerror
    :捕获IE中的所有错误(以及Firefox中的大多数错误),但在Safari和Opera中不执行任何操作
  • jQuery事件处理程序:捕获所有浏览器中的jQuery事件错误
  • jqueryready函数:捕获所有浏览器中的初始化错误

实际上,jquery方法并没有那么糟糕。见:

以及:


try catch
并不总是最好的解决方案。例如,在Chrome7.0中,您会在控制台窗口中丢失漂亮的堆栈跟踪。重新引用异常没有帮助。我不知道有哪种解决方案可以保留堆栈跟踪并让您对异常做出反应。

使用您自己的异常处理程序捕获所有异常并使用instanceof

$("inuput").live({
    click : function (event) {
        try {
            if (somethingGoesWrong) {
                throw new MyException();
            }
        } catch (Exception) {
            new MyExceptionHandler(Exception);
        }

    }
});

function MyExceptionHandler(Exception) {
    if (Exception instanceof TypeError || 
        Exception instanceof ReferenceError || 
        Exception instanceof RangeError ||  
        Exception instanceof SyntaxError ||     
        Exception instanceof URIError ) {
        throw Exception; // native error
     } else {
         // handle exception
     }
}
MyExcetpionHandler将抛出本机错误,因为没有try-catch块


访问

我也在寻找错误处理、stacktrace和用户操作日志这就是我发现的希望这也能帮助你

只需稍加努力,就可以获得在所有浏览器中都相当完整的堆栈跟踪

现代Chrome和Opera(即基于Blink渲染引擎的任何东西)完全支持ErrorEvent和
window.onerror的HTML5草案规范。在这两种浏览器中,您可以使用
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
    // sendData(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
    // sendData(data);
})
不幸的是,Firefox、Safari和IE仍然存在,我们也必须支持它们。由于stacktrace在
窗口中不可用。OneError
我们需要做更多的工作

事实证明,要从错误中获取stacktrace,我们唯一能做的就是将所有代码包装在
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
                // sendData(data);
                throw e;
            }
        }
    }
    return func._wrapped;
};
这很有效。手动包装的任何函数都具有良好的错误处理能力

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
                // sendData(data);
                throw e;
            }
        }
    }
    return func._wrapped;
};
您可以使用图像标记发送数据,如下所示

function sendData(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;
}
但是,您必须在后端收集数据,在前端可视化数据

目前,我们正在努力解决这个问题。除了错误跟踪,Atatus还提供了真正的用户监控

试一试


免责声明:我是Atatus的一名web开发人员。

的确,在现代浏览器中,挂起window.OneError查找冒泡的错误,并为Ajax错误添加jQuery事件处理程序,将捕获客户端代码中抛出的几乎所有错误对象。如果手动设置window.onerror的处理程序,在现代浏览器中,这是通过
window.addEventListener('error',callback)
完成的, 在IE8/9中,您需要致电
window.attachEvent('onerror',回调)

请注意,您应该考虑这些错误正在被处理的环境,以及这样做的原因。使用StackTrace捕获尽可能多的错误是一回事,但是现代F12开发工具的出现在本地实现和调试时解决了这个用例。断点等将为您提供比处理程序提供的数据更多的数据,特别是对于从CORS请求加载的第三方库引发的错误。您需要采取其他步骤来指示浏览器提供此数据

关键问题是在生产中提供这些数据,因为您的用户保证运行的浏览器和版本比您可能测试的要广泛得多,并且您的站点/应用程序将以意想不到的方式崩溃,无论您对其进行了多少QA

要处理这个问题,您需要一个生产错误跟踪器,它在用户使用您的代码时收集用户浏览器中抛出的每个错误,并将它们发送到一个端点,您可以在该端点查看数据,并在错误发生时用以修复错误。在RayFAR(免责声明:我在Ray枪公司工作)中,我们投入了大量的精力来提供一个很好的经验,因为有很多陷阱和问题需要考虑,一个幼稚的实现将丢失。 例如,您很可能会绑定并缩小JS资产,这意味着从缩小的代码中抛出的错误将具有带有损坏变量名的垃圾堆栈跟踪。为此,您需要您的构建工具来生成源映射(对于管道的这一部分,我们建议使用UglifyJS2),并需要您的错误跟踪器来接受和处理这些源映射,将损坏的堆栈跟踪转换回人类可读的源映射。Raygun可以直接完成所有这些工作,并包括一个API端点,用于在构建过程生成源映射时接受源映射。这是关键,因为它们需要保持非公开,否则任何人都可以取消您的代码的统一,从而否定其目的

客户端库还为现代浏览器和传统浏览器提供了
window.onerror
,以及jQuery现成的挂钩,因此要设置它,只需添加: