Vue中的错误处理


去年全年,我使用自己喜欢的框架Vue.js进行了描述和表示。 而且我意识到我还没有想到Vue中的错误处理。 我想通过说我正在编写完美的代码来解释这一点,但是我们都知道事情的真相。 在过去的几天里,我尝试了Vue提供的各种错误处理方法,并决定分享我的发现。 显然,此评论不会涵盖所有可能的情况,但希望对您有所帮助!

失误


为了测试不同的处理方法,我决定采用三种不同类型的错误(至少从头开始)。 在第一种情况下,它只是对不存在的变量的调用:

<div id="app" v-cloak> Hello, {{name}} </div> 

在此示例中,用户未收到错误消息,但控制台中显示警告[Vue warn]。



这是此示例的执行结果:


在第二个示例中,我尝试将变量绑定到应该产生错误的计算属性:

 <div id="app" v-cloak> Hello, {{name2}} </div> 

 const app = new Vue({ el:'#app', computed:{ name2() { return x; } } }) 

在这种情况下,[Vue warn]警告和通常的错误消息都会显示在控制台中,但不会向用户发出任何消息。



这是本示例代码的运行方式:


在第三个示例中,我使用了应该引发错误的方法。

 <div id="app" v-cloak> <button @click="doIt">Do It</button> </div> 

 const app = new Vue({ el:'#app', methods:{ doIt() { return x; } } }) 

与前面的情况一样,控制台中将显示两次有关此错误的消息:一条警告和一条有关此错误的消息。 但是,与他不同,仅当实际按下按钮时才会发生错误。



这是此示例的演示:


在继续之前,我想弄清楚这些示例并没有显示您可能犯的所有错误。 这些只是主要的几个,我认为通常可以在基于Vue.js的应用程序中找到。

那么,如何处理Vue应用程序中的错误? 我必须说,令我有些惊讶的是,在Vue框架的主要指南中没有关于错误处理的章节。



是的,手册中有一个类似的部分,但是它很短,其全部含义适合以下引用:

“如果在组件渲染期间发生运行时错误,则如果指定了运行时错误,它将被传递到全局配置函数Vue.config.errorHandler。 将此挂钩与诸如Sentry之类的错误跟踪服务结合使用可能会很有用,特别是因为它已正式支持与Vue的集成。”

我认为,该主题应在文档中多介绍一些(我认为它可以对其进行补充)。 通常,Vue中的错误处理可归结为以下几种方式:

  • errorHandler;
  • warnHandler;
  • renderError;
  • errorCaptured;
  • window.onerror (此工具并非特定于Vue)。

让我们仔细看看这些技巧。

第一错误处理程序:errorHandler


第一个补救方法是errorHandler 。 您可能已经猜到了,这是Vue.js应用程序的标准错误处理程序。 您可以按以下方式分配它:

 Vue.config.errorHandler = function(err, vm, info) { } 

在上面的函数声明中,err是当前错误的描述,info是特定于Vue的错误信息的字符串,vm是当前Vue应用程序。 请记住,多个Vue应用程序可以同时在同一网页上运行。 此错误处理程序将适用于所有对象。 考虑以下简单示例:

 Vue.config.errorHandler = function(err, vm, info) { console.log(`Error: ${err.toString()}\nInfo: ${info}`); } 

在第一个错误的情况下,此代码不执行任何操作。 如果您还记得的话,这会生成警告 ,而不是错误消息。

在第二种情况下,将处理错误并显示以下文本:

 Error: ReferenceError: x is not defined Info: render 

最后,第三个示例给出以下结果:

 Error: ReferenceError: x is not defined Info: v-on handler 

请注意,在前面两个示例中的信息标题下,信息有多“有用”。 现在,让我们检查以下工具的工作原理。

错误处理程序二号:warnHandler


warnHandler句柄-您会怎么想? -Vue警告。 请注意,在生产中,此处理程序将被忽略。 此方法的处理程序也与上一个稍有不同:

 Vue.config.warnHandler = function(msg, vm, trace) { } 

前两个参数-msg和vm-无需进一步说明,并且trace参数必须是组件树。 考虑一个例子:

 Vue.config.warnHandler = function(msg, vm, trace) { console.log(`Warn: ${msg}\nTrace: ${trace}`); } 

现在,第一个示例具有针对其生成的警告的处理程序,并返回以下内容:



第二和第三示例保持不变。 下面提供了这三种情况的实时示例。




第三错误处理程序:renderError


现在,我将演示第三个错误处理方法:renderError。 与前两个不同,此工具取决于组件,并且不是通用的。 与warnHandler一样,此生产处理程序也被禁用。

要使用它,请将其插入到组件/应用程序中。 以下是文档中的修改示例。

 const app = new Vue({ el:'#app', renderError (h, err) { return h('pre', { style: { color: 'red' }}, err.stack) } }) 

如果在第一个示例中使用了此错误处理程序,则它什么也不做,如果考虑一下,这似乎是合乎逻辑的,因为第一个示例给出了警告,而不是错误。 如果在第二个示例中检查此处理程序,则计算所得的属性给出错误,则您会看到其结果显示在屏幕上。 您可以在下面的codePen演示中看到这一点。


老实说,当控制台更加方便时,我不明白为什么要使用此工具,但是如果质量控制部门或其他测试人员对浏览器控制台不熟悉,那么屏幕上出现一条简单的错误消息可以为他们提供帮助。

第四个错误处理程序:errorCaptured


最后,有一个errorCaptured工具(特定于Vue)使我感到困惑,并且坦率地说,仍然有些混乱。 该文档说:

“如果任何子组件中发生错误,则调用。 该钩子接收三个参数:错误,导致错误的组件实例以及包含有关错误记录位置信息的字符串。 挂钩可能返回false,以防止错误进一步传播。”

根据我的研究(再次,我对此表示强烈怀疑),该错误处理程序应仅由处理子组件错误的父组件使用。 据我所知,它不能在主Vue实例中使用,而只能在具有子代的组件中使用。

为了检查这一点,我创建了这组父子组件:

 Vue.component('cat', { template:` <div><h1>Cat: </h1> <slot></slot> </div>`, props:{ name:{ required:true, type:String } }, errorCaptured(err,vm,info) { console.log(`cat EC: ${err.toString()}\ninfo: ${info}`); return false; } }); Vue.component('kitten', { template:'<div><h1>Kitten: {{ dontexist() }}</h1></div>', props:{ name:{ required:true, type:String } } }); 

请注意,小猫组件包含错误。 现在,如果我尝试按以下方式使用此组件,

 <div id="app" v-cloak> <cat name="my cat"> <kitten></kitten> </cat> </div> 

我将从处理程序中收到一条消息:

 cat EC: TypeError: dontexist is not a function info: render 

您可以在下面的示例中看到这一点。


是的,这是一个有趣的工具。 我相信它将主要由那些创建具有父/子关系的组件库的人使用。 如果这种划分有意义,那么该工具更适合于库开发人员而不是普通开发人员。 但是,这只是我对该工具的第一印象。

一个用于管理世界上所有事物的工具:window.onerror



最后一个(也是最强大的)选项是使用window.onerror ,它是执行JavaScript代码时可能发生的一切的全局错误处理程序。 该处理程序具有以下格式:

 window.onerror = function(message, source, line, column, error) { } 

您可能无法在上述代码中猜测的唯一一件事就是source参数的含义,即脚本的URL。

这就是乐趣的开始。 如果您定义此函数,但使用Vue.config.errorHandler,它将无法为您提供帮助。 Vue希望您定义Vue.config.errorHandler,否则,它将不会传播错误超出其限制。 可能这是有道理的...我什至不知道,对我而言这没有多大意义。 甚至更奇怪的事情:假设您的Vue错误处理程序本身存在错误。 它也不会到达window.onerror处理程序。

这是CodePen上的演示以及相应的示例。 我注释了errorHandler中的错误,但是如果删除注释,您将看到全局错误处理程序将无法工作。 仅在一种情况下有效:如果您按下第二个按钮。


结论


我希望本文中的内容对读者有用。 正如一开始所写的那样,我刚刚开始处理这个主题,因此,我当然在等待评论,评论和建议。 我很高兴阅读其他开发人员如何在其应用程序中使用这些工具!

文章开头的照片:作者-David Kovalenko ,Unsplash网站

Source: https://habr.com/ru/post/zh-CN460539/


All Articles