如何在前端搜索错误:4个主要阶段


在本文中,我将考虑识别和处理前端(浏览器或Web视图)上发生的错误的问题。

在前端,JS代码在浏览器中执行。JavaScript不是一种编译语言,因此直接使用该程序时始终会出现性能错误。执行错误会阻止位于错误位置之后的代​​码,并且程序用户可能会面临只能重新加载或关闭的无法运行的应用程序屏幕的风险。但是有避免错误的方法及其安全陪伴,可以避免这种情况。

1. JavaScript工具


尝试/抓挡


可能失败的功能可能包含在try / catch块中。首先,程序尝试执行try块中的代码。如果由于某种原因导致代码执行中断,则程序进入catch块,该块中有三个参数可用:

  • 名称-错误的标准化名称;
  • 消息-有关错误详细信息的消息;
  • 堆栈-发生错误的当前调用堆栈。

即:

try {

   callFunc();

} catch (e) {

   console.log(e.name) // ReferenceError

   console.log(e.message) // callFunc is not defined

   console.log(e.stack) // ReferenceError: callFunc is not defined at window.onload

}

对于开发人员来说,最主要的是程序可以在catch块之后继续执行。因此,用户交互不会被打断。

使用try / catch块,还可能导致您自己的错误,例如,在检查数据时:

const user = {

  name : «Mike»

};

try {

   if (!user.age) throw new SyntaxError(«User age is absent!»);

} catch (e) {

   console.log(e.name) // SyntaxError

   console.log(e.message) // User age is absent!

   console.log(e.stack) // SyntaxError: User age is absent! at window.onload

}

最后,您可以再增加一个块来扩展此语句-最后,该块始终执行:在try中没有错误的情况下,以及在控制权传递给catch块的情况下:

try {

   callFunc();

} catch (e) {

   console.log(e)

} finally {

   ...

}

有时他们使用try / finally语句(不带catch),以便您可以继续使用代码而无需处理特定的错误。

Window.onerror事件


即使程序已损坏并且用户会话未成功结束,知道页面上的脚本已损坏通常也很有用。通常,此信息然后用于错误记录系统。

全局窗口对象有一个onerror事件(请谨慎使用:不同浏览器的实现可能有所不同!):

window.onerror = function(message, url, line, col, error) {

   console.log(`${message}\n  ${line}:${col}  ${url}`);

};

如果您将此代码放在脚本的开头,或者首先将其加载到单独的脚本中,那么对于开发人员下面的任何错误,都将提供有关它的详细信息。

但是,完整的信息仅适用于从同一域下载的脚本。如果损坏的脚本是从另一个域加载的,则window.onerror将起作用,但是将没有错误的详细信息。

框架组件


一些JS框架(React,Vue)提供了自己的错误处理解决方案。例如,React将能够在发生错误的块的位置绘制特殊的布局:

class ErrorBoundary extends React.Component {

   constructor(props) {

       super(props);

       this.state = { hasError: false };

   }

   static getDerivedStateFromError(error) {

       //    ,      UI.

       return { hasError: true };

   }

   componentDidCatch(error, errorInfo) {

       //           

       logErrorToMyService(error, errorInfo);

   }

   render() {

       if (this.state.hasError) {

           //    UI  

           return <h1>-   .</h1>;

       }

       return this.props.children;

   }

}

<ErrorBoundary>

   <MyWidget />

</ErrorBoundary>

实际上,React组件被包装在处理错误的特殊组件中。这类似于使用try / catch结构包装函数。

2.项目组装工具


现代JS脚本通常是转译的。即,使用最新的ES标准进行开发。然后,使用项目构建器(例如Webpack)的开发人员的代码将转换为可以保证在选定数量的浏览器中工作的代码。

在构建阶段,将检查代码中的语法是否正确。开括号或类别字段的错误指定将立即在组装过程中引起错误,并且捆包将根本无法组装。开发人员将必须立即修复此类错误才能继续工作。

同样,收集器可能建议在执行程序时不使用某些代码。也许这将促使开发人员考虑对代码进行更深入的研究,这可能会间接影响对新错误的识别。

3.测试


防止代码错误的另一种方法是对其进行测试。前端中有一些工具可以有效地使用单元测试。通常,使用诸如Jest,Karma,Mocha,Jasmine之类的框架。除了测试框架外,他们还经常使用诸如酶,React测试库,Sinn等扩展程序,这些扩展程序可以借助模拟,间谍功能和其他工具来丰富测试。

搜索错误时,测试对于加载可能导致执行错误的各种数据非常有用。因此,以下代码将通过语法验证并按预期工作:

const func = (data) => {

   return JSON.parse(data)

}

func('{«a»:1}')

但是,如果您给它错误的值,它将破坏:

func() // Uncaught SyntaxError: Unexpected token u in JSON at position 0.


此代码还在汇编过程中通过了验证:

const obj = {

   outer : {

       last : 9

   }

}

if (obj.outer.inner.last) {

   console.log(«SUCCESS»)

}

但是,它也会在执行期间中断。经过测试后,开发人员可能会进行其他检查:

if (obj.outer?.inner?.last) {

   console.log(«SUCCESS»)

}

通常,从服务器接收数据(例如,通过AJAX请求)并进行后续分析时,会发生此类错误。通过测试代码,您可以提前识别并消除在客户端浏览器中执行过程中代码可能中断的情况。

4.记录


假设我们已采取所有可能的措施来防止在项目的开发和组装过程中出错。但是,错误仍然会渗透到生产性代码中。我们需要以某种方式找出它们的存在并立即采取纠正措施。要求用户打开浏览器控制台并进行屏幕截图不是最佳选择。因此,最好将错误日志记录连接到项目。

含义很简单:对于每个window.onerror事件或代码执行到catch块的每次转换,都会向专门分配的服务器地址发出一个简单的AJAX请求,并在其中放置有关错误的信息。接下来,您将需要一个工具,该工具可以将新错误的出现迅速通知技术支持和开发人员,并使您可以有效地与他们合作。这些前端工具中最受欢迎的是Sentry。

Sentry日志记录系统使您可以实时收集,分组和显示错误。有用于不同语言的程序集,包括JavaScript。该项目提供了具有高级功能的付费访问业务,但是,您可以在免费的测试帐户上试用其主要功能。

Sentry可以直接连接到HTML文件中,也可以连接到在一种流行的框架上执行的组件中:React,Vue,Angular,Ember等。

要在部分的浏览器中直接连接日志记录功能,请加载脚本:

<script

   src=«https://browser.sentry-cdn.com/5.13.0/bundle.min.js»

   integrity=«sha384-ePH2Cp6F+/PJbfhDWeQuXujAbpil3zowccx6grtsxOals4qYqJzCjeIa7W2UqunJ»

   crossorigin="anonymous"></script>


接下来,在JS代码中,我们初始化:

Sentry.init({

   dsn: 'https://<your account key here>@sentry.io/<your project id here>'

});

所有。如果并且在此行下方的代码中发生错误,Sentry将对其进行记录。即使由于其他域的脚本错误而导致发生错误,也会记录日志:



Sentry有足够的机会分析一系列错误消息并配置通知。还可以按产品版本对错误日志进行分组:

Sentry.init({

   dsn: 'https://<your account key here>@sentry.io/<your project id here>',

   release: '2020.03.06.1'

});

使用Sentry,统计信息可用于传输错误的上下文,例如,客户信息,指纹,错误级别(严重,错误,警告,信息,调试)和标签。

可以在统计信息中记录用户事件。例如,您可以设置跟踪以更改浏览器窗口的大小或发出AJAX请求。Sentry也有自己的带有反馈窗口的小部件,如果出现错误,可以将其显示给用户。这将提供更多信息来调查错误的情况。

要将Sentry与框架一起部署,只需安装软件包并连接:

# Using yarn

yarn add @sentry/browser

# Using npm

npm install @sentry/browser


我们在项目的主脚本中进行初始化(针对React和Angular):

import * as Sentry from «@sentry/browser»;

Sentry.init({ dsn: 'https://<your account key here>@sentry.io/<your project id here>' });


对于Vue和Ember,我们传递了另一个必需的配置行:

# Vue

Sentry.init({

   dsn: '<your account key here>@sentry.io/<your project id here>',

   integrations: [new Integrations.Vue({Vue, attachProps: true})],

});

# Ember

Sentry.init({

   dsn: '<your account key here>@sentry.io/<your project id here>',

   integrations: [new Integrations.Ember()]

});

集成软件包是单独安装的:

# Using yarn

yarn add @sentry/integrations

# Using npm

npm install @sentry/integrations

为防止在一个项目中连接多个脚本时发生冲突和信息重复,Sentry允许您为每个日志记录初始化创建一个单独的客户端:

import { BrowserClient } from «@sentry/browser»;

const client = new BrowserClient({

   dsn: '<your account key here>@sentry.io/<your project id here>',

});

client.captureException(new Error('example'));

项目网站上有详细的文档以及使用示例:https : //docs.sentry.io

本文是在Mail.ru云解决方案云平台的支持下编写的

关于该主题还需要阅读什么:

  1. Reactable React组件:如何停止编写相同的组件
  2. 在React上开发时如何避免错误
  3. - .

All Articles