JavaScript 错误处理的最佳实践是啥?

Posted

技术标签:

【中文标题】JavaScript 错误处理的最佳实践是啥?【英文标题】:What are the best practices for JavaScript error handling?JavaScript 错误处理的最佳实践是什么? 【发布时间】:2011-09-22 23:51:41 【问题描述】:

我希望开始让我的 javascript 更加防错,并且我找到了大量关于使用 trycatchfinallythrow 的文档,但我没有从专家那里获得大量关于何时何地抛出错误的建议。

是否应该将每段代码都包装在 try/catch 中? 是否有更多类似this on 的建议应该在什么时候发现错误? 引发错误而不是让代码在生产中静默失败有什么缺点吗? 就实现而言,SO 已经谈到了这一点,但是服务器记录 JS 错误是否是一种有效的策略? 关于在我的应用程序中捕获错误,我还应该知道什么?

我也完全喜欢听那些有精彩章节或深入解释错误处理的书籍。 Eloquent JavaScript 涉及此事,但对这个问题不是很规范或固执己见。

感谢您提供的任何建议!

【问题讨论】:

这肯定取决于出现问题时失败的严重程度以及可能出现的错误消息的数量。您不想因为错误日志目录已满而失败吗? - 你看过这里吗? ***.com/search?q=error+logging+javascript @mplungjan - 我确实浏览了那里的答案,但似乎没有很多规范,并且搜索 Javascript 错误处理/异常最佳实践没有任何结果,所以我认为尝试和征求一些浓缩的想法,以供我自己的理解和未来的搜索者使用。也许这是一个不可能规定最佳实践的话题,但每种情况都非常独特? "是否应该将每段代码都包装在 try/catch 中?"当然不是。有很多你知道总是可以工作的代码(当然,假设你测试了它,但是 try/catch 的重点不是捕捉或掩盖编码错误)。仅包装由于超出其控制范围而可能在某些时候失败的代码,通常是资源访问等。注意:一些可能失败的事情具有内置的错误处理,例如,我不会费心从头开始编写 Ajax 时有很多库可以处理跨浏览器问题并让您指定错误处理函数。 这是一个很好的问题,乔希,+1。周围有很多语法建议,但就像你说的那样,这很容易。在这个问题的答案 (***.com/questions/2825427/…) 中提到了这一点,其中解释了异常在 JS 中不常用,并给出了原因。 【参考方案1】:

可以在https://web.archive.org/web/20140126104824/http://www.devhands.com/2008/10/javascript-error-handling-and-general-best-practices/找到一组非常有趣的关于企业 JavaScript 错误处理的幻灯片

总结如下:

    假设您的代码将失败 将错误记录到服务器 处理错误的是您,而不是浏览器 确定可能发生错误的位置 抛出你自己的错误 区分致命错误和非致命错误 提供调试模式

幻灯片更详细,很可能会给你一些指导。

编辑:

可以在此处找到上述演示文稿: https://www.slideshare.net/nzakas/enterprise-javascript-error-handling-presentation

【讨论】:

devhands 链接已损坏。 对于那些在 2017 年读过这篇文章的人,我认为你不会从幻灯片中获得太多价值 - 这个摘要为你提供了 90% 的信息。它仍然是有价值的信息。干杯!【参考方案2】:

Yahoo! 的 Nicholas Zakas Fame 在 Ajax Experience 2008 上发表了关于企业错误处理 (slides) 的演讲,其中他提出了这样的建议:

function log(sev,msg) 
    var img = new Image();
    img.src = "log.php?sev=" +
        encodeURIComponent(sev) +
        "&msg=" + encodeURIComponent(msg);


// usage
log(1, "Something bad happened.")

// Auto-log uncaught JS errors
window.onerror = function(msg, url, line) 
    log(1, msg);
    return true;

一年后,Nicholas Zakas 发布了一个 update on his blog,其中包含一个巧妙的模式,可以在您的生产环境中自动注入错误处理代码(使用面向方面的编程)。

当您开始记录 window.error 调用时,您会注意到两件事:

    如果您的网站相当复杂,您会记录很多错误 您会看到一堆无用的“window.error in undefined:0”消息

减少日志条目的洪流就像在登录到服务器之前测试严重性和/或随机数一样简单:

function log(sev,msg) 
    if (Math.random() > 0.1) return; // only log some errors

    var img = new Image();
    img.src = "log.php?sev=" +
        encodeURIComponent(sev) +
        "&msg=" + encodeURIComponent(msg);

处理无用的 window.error in undefined:0 错误取决于您的站点架构,但可以尝试识别所有 Ajax 调用并在出现故障时抛出异常(可能使用 stacktrace.js 返回堆栈跟踪)。

【讨论】:

我知道这是一个老问题,但建议随机忽略一些错误是我听过的最糟糕的想法之一。 @jbabey:对于小型站点,您是对的,但是如果您正在运行一个拥有 100,000 或数百万用户的大型站点,您真的不需要淹没您的服务器(或互联网)带有冗余的日志记录请求。在一个足够大的系统上,每个真正的错误每天都会发生数万次,所以这种形式的限制工作得很好。这个想法实际上是在 Facebook 实现的。 在调试模式下记录错误可能与限制生产错误报告一样重要,因此可能需要一种解决方案来管理限制记录阈值的值。 @NickBull 我在 2011-2012 年逆向工程了一堆 Facebook 的 JavaScript 模块;那是我找到它的地方。 @NickBull 刚刚检查了我的旧文件,仍然有这些。我在 Facebook 引导加载程序模块中发现了这个技巧:if (global.logJSError) if (Math.random() < .01) logJSError('bootloader', (诚然,该代码不会限制所有错误,只会限制特定类别的超时错误)【参考方案3】:

IHMO,您应该像使用其他几种语言(AFAIK:Python、Java)一样在 javascript 中使用错误处理。

为了更好的可读性(可能还有更好的性能,尽管我不确定它是否有很大的影响),您应该主要在以下情况下使用 try / catch 块:

您要包装的代码部分是关键整个算法的一部分。如果失败,它可以:

在代码的下一部分创建错误(例如,因为缺少 var...) 使页面看起来不像预期的那样(对内容或 css 的影响) 让结果对用户来说显得陌生(对代码行为的影响)

您知道您正在编写的代码并非与所有浏览器都兼容

您计划代码可能会失败(因为没有其他方法可以通过 if...then... 块检查它是否应该工作) 当您想要调试而不打扰最终用户时

最终,javascript 专家可能会提供其他元素。

我的 2 美分到盒子里,

问候,

最大

【讨论】:

“您要包装的代码部分是整个算法的关键部分” - 可能取决于您要如何处理故障。如果您知道在失败时无法继续使用该算法,那么最好将整个事情包装在 try/catch 中,因为如果您的 try/catch (例如)埋在嵌套循环中,它将更多地影响性能.另一方面,如果您可以对异常采取一些措施并继续使用算法,那么您将需要更细粒度的 try/catch 设置。【参考方案4】:

除了其他答案:一件重要的事情是使用 JavaScript 错误对象和 window.onerror 函数参数中可用的上下文数据

诸如堆栈跟踪(errorObject.stack)、文件名、行号和列号之类的东西。 请注意,每个浏览器都有一些差异......所以尽你最大的努力得到好的错误。

console object itself 甚至可能存在问题。 我使用a custom window.onerror function inspired by this one 和一个特殊函数来跟踪受this code 启发的任何给定标准错误对象。

另一个好处是将 Web 应用程序的版本包含在堆栈跟踪附近的某个位置(以便快速安全地复制和粘贴)。您还可以在开发模式下更积极地显示错误(警报...),因为开发人员不会持续监控浏览器控制台,并且可能看不到某些问题。

同样使用避免使用throw 'My message',使用throw new Error('My message'),你甚至可以有自定义错误,阅读this article。

始终为错误添加一些上下文(版本、对象的 id、一些自定义消息……),并确保区分外部错误(一些外部数据或环境导致系统失败)和内部错误/断言(您自己的系统搞砸了),请阅读“Design by contract”。

这是guide。

还可以考虑使用通用错误处理,例如拦截器和框架:

jQuery Angular 1.x 和 for http Angular 2.x 你的新涂料框架在这里......

【讨论】:

【参考方案5】:

我为此创建了脚本。它阻止除了允许列表中提到的项目之外的所有控制台命令,或阻止阻止列表中的所有内容。即使使用彩色控制台日志也能正常工作。

https://github.com/iiic/consoleFilter.js

【讨论】:

以上是关于JavaScript 错误处理的最佳实践是啥?的主要内容,如果未能解决你的问题,请参考以下文章

在 redux 中处理异步操作错误的最佳实践是啥?

防止过时的 CSS 和 JavaScript 的最佳实践是啥

带有 JavaScript 后端和前端的多人游戏。最佳实践是啥?

Javascript 在这种情况下使用 IF 或 SWITCH 或“动态函数名”的最佳实践是啥

这是编写以在javascript / node js中处理错误处理then-catch或try-catch的最佳实践[重复]

CSS3 - 性能最佳实践是啥? [关闭]