【问题标题】:Any way to stop Javascript from failing silently?有什么方法可以阻止 Javascript 静默失败?
【发布时间】:2011-04-25 21:12:26
【问题描述】:

让我发疯的一件事是 Javascript 在许多不同的情况下如何默默地失败。

(删除示例,因为它混淆了我的问题的重点)

很多时候我遇到一个错误,当输入到 Firebug 控制台时会给出错误消息,但是当它在页面脚本中运行时,它会默默地失败,即使 Firebug 控制台处于活动状态并打开!

Crockford 的 JsLint 可以发现其中一些问题,但仍有许多问题不会。

有没有办法在浏览器中启用更多错误消息?

你可以在不使用 javascript 调试器环境的情况下做到这一点吗?我发现调试器对我帮助不大。我一般撒几条console.log()语句,一分钟就能定位问题。让我抓狂的是,Javascript 中的静默错误可能会在很长一段时间内被忽视,或者以根本不明显的方式出现。更令人沮丧的是,因为在控制台中测试语句确实会出错,所以这是怎么回事?

顺便说一句,我遇到了同样的异常问题,有人注意到了吗?很多时候我的throw new 语句根本不起作用。但是,如果我在控制台中输入相同的内容,它就会出现。

感谢您提供帮助的 cmets(第一个答案),但这不是我的问题。当您需要清理类的参数时,这些测试很有用,例如,当您不确定环境时。您不想测试您期望它们存在的属性或类的存在;那会无缘无故地使代码膨胀。

【问题讨论】:

  • 静默错误是什么意思?当网页在浏览器中运行时,默认情况下所有 JavaScript 错误都是无声的,因为没有必要将它们显示给网站的访问者。
  • 我想我想知道雅虎和谷歌的 Javascript 专家在做什么。他们有一个很棒的编译器,还有 JsLint,但这还不够。我不敢相信他们会忍受这些。我肯定错过了什么。我试图弄清楚是否必须使用 Microsoft 提供的调试环境,或者是否有其他方法可以在开发人员模式下运行浏览器并在控制台中查看所有这些错误。为什么当页面运行时 Firebug 保持沉默,但当我在控制台中输入违规代码时显示错误(控制台始终打开)?

标签: javascript debugging exception-handling firebug


【解决方案1】:

我认为这个问题的一些答案误解了这个问题。 IIUC,问题是当此代码在真实网页中运行时,错误 is 被压制,但 OP 不希望它出现。 (大概主要是为了调试目的。)

然后我的问题是,这段代码真的在网站上下文中运行在哪里?有可能是其他东西在错误到达您之前将其压制了。例如,一些库可能会本能地抑制特定回调中发生的错误(例如,对于 XHR)。但是,如果它们很好,它们也会提供一个挂钩点,以便在发生错误时接收通知。

【讨论】:

  • 你是对的。既然您提到了它,我想我有时会看到 YUI (YUI 2.8) 捕获的错误。也许他们在 try catch 块中运行了很多代码?我将在 try catch 块中测试运行我的代码,看看会发生什么。
  • 简单的回调例如表单输入将愉快地吞下异常而不留痕迹。实际上,我到处都有防御性尝试捕获,以确保记录错误。除非我在处理程序中也放了一个 try catch,否则这些似乎都无法捕获处理程序异常。恕我直言,任何假定回调没有错误的地方都被设计破坏了。像javascript这样的动态语言可能并且将会发生错误。简单的引用或类型错误或未定义的错误一直在发生。如果浏览器总是记录未捕获的异常,那就太棒了。
  • 这是非常正确的。几个月后我才意识到,这就是我的错误没有在 Firefox 控制台中弹出的确切原因。在 webextension 开发的上下文中,'browser.tabs.sendMessage' 甚至可以捕获内容脚本中的异常。谢谢!
【解决方案2】:

下面的代码将捕获catch块中的所有错误:

var a;
try {
    a = new Foo.Apple();
} catch (err) {
    // Error handling
}

欲了解更多信息:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/try...catch

【讨论】:

  • -1 用于在块内声明变量。变量声明语句应该是执行上下文的第一条语句。在“程序中间”声明变量是一种不好的做法。
  • 另外,我相信防御性存在检查比强制错误要好得多。
  • 你对变量声明是正确的,在评论中修复了它。关于存在性检查,如果你需要具体知道哪个声明失败了,你是对的,但是在无关紧要并且有很多检查的情况下,我认为这要好得多。
  • 我把 -1 颠倒了,因为你修好了。但是,在有很多检查的情况下,无论如何,您无法根据捕获的错误对象判断哪个检查失败。如果您调用多个构造函数并且其中一个未定义,则您无法根据捕获的 TypeError 判断哪个失败。
  • 谢谢。我的观点是,如果您不需要知道哪个失败(如果您调用多个构造函数),则不需要所有 if/else 块,它们只会使源代码混乱。
【解决方案3】:

如果您正在处理不确定它们在运行时是否存在的对象,则必须检查它们是否存在:

if (Foo && Foo.Apple) {
    // exists, do something with it
} else {
    // doesn't exist, do Plan B
}

请注意,表达式 (Foo && Foo.Apple) 将首先检查 Foo 是否存在,并且仅当存在时,它才会检查它是否具有名为 Apple 的属性。如果有,if-branch 将执行。

如果 Foo 不存在,或者如果它不包含 Apple 属性,则 else-branch 将执行。

【讨论】:

  • 你是对的,但这个特殊的问题是我的 javascript“包”中有一个组件没有加载。代码不希望该组件不存在,它是一个依赖项。我的问题更多是关于找到一种获取通知的方法,而不是有时令人沮丧的无声错误。
  • 好吧,如果你有多个组件,你必须采取防御姿态,并考虑一个组件可能无法加载/执行的可能性。当然,您希望它确实存在,但您不能确定。这就是为什么您要进行防御性编程并始终首先使用 if 语句检查特定组件是否存在。如果存在,很好,如果不存在,使用 else-branch 作为“通知”。当然,你可以利用 else-branch 再次尝试加载组件(例如)。
【解决方案4】:

同意@sime Vidas,如果必须处理异常并且不保持沉默,首先使用布尔条件并检查该值是否存在。

if(Foo.Apple){
\\your code
}
else
{
//Foo.Apple does not exist, do some exception handling here
}

【讨论】:

    猜你喜欢
    • 2022-06-15
    • 2011-04-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多