我们正在探索将 Sentry 与 React 结合使用。
本文是系列文章的一部分,首先使用示例报告 Sentry 错误:
反应的实现
首先我们需要为此应用程序添加一个新的Sentry项目; 来自哨兵网站。 在本例中我们选择 React。
我们将使用 React 在应用程序中重新实现两个按钮:Hello 和 Error。 我们首先创建我们的入门应用程序:
npx create-react-app react-app
然后我们导入Sentry包:
yarn add @sentry/browser
并初始化它:
反应应用程序/src/index.js
...
import * as Sentry from '@sentry/browser';
const RELEASE = '0.1.0';
if (process.env.NODE_ENV === 'production') {
Sentry.init({
dsn: 'https://[email protected]/1289887',
release: RELEASE,
});
}
...
观察结果:
- 在开发过程中,我们有其他机制来监控问题,例如控制台,因此我们仅启用 Sentry 进行生产构建
接下来我们实现 Hello 和 Error 按钮并将它们添加到应用程序中:
反应应用程序/src/Hello.js
import React, { Component } from 'react';
import * as Sentry from '@sentry/browser';
export default class Hello extends Component {
state = {
text: '',
};
render() {
const { text } = this.state;
return (
<div>
<button
onClick={this.handleClick}
>
Hello
</button>
<div>{text}</div>
</div>
)
}
handleClick = () => {
this.setState({
text: 'Hello World',
});
try {
throw new Error('Caught');
} catch (err) {
if (process.env.NODE_ENV !== 'production') {
return;
}
Sentry.captureException(err);
}
}
}
反应应用程序/src/MyError.js
import React, { Component } from 'react';
export default class MyError extends Component {
render() {
return (
<div>
<button
onClick={this.handleClick}
>
Error
</button>
</div>
)
}
handleClick = () => {
throw new Error('Uncaught');
}
}
反应应用程序/src/App.js
...
import Hello from './Hello';
import MyError from './MyError';
class App extends Component {
render() {
return (
<div className="App">
...
<Hello />
<MyError />
</div>
);
}
}
export default App;
问题(源图)
我们可以通过输入以下内容来测试 Sentry 的生产版本:
yarn build
并从构建文件夹中输入:
npx http-server -c-1
我们立即遇到的问题是 Sentry 的错误记录引用了缩小批次中的行号; 不是很有用。
Sentry 服务通过在收到错误后拉取缩减数据包的源映射来解释这一点。 在本例中,我们从本地主机运行(Sentry 服务无法访问)。
解决方案(源图)
此问题的解决方案是从公共 Web 服务器运行应用程序。 一个简单的回复按钮即可使用 GitHub Pages 服务(免费)。 使用步骤通常如下:
-
复制文件夹内容 建立 到文件夹 文档 在存储库的根目录中。
-
打开 GitHub页面 在存储库(来自 GitHub)中使用 docs 文件夹 主 分支机构
-
将更改推送到 GitHub
注意: 在我弄清楚我需要使用什么之后 创建-创建-应用程序 主页功能来启动应用程序。 最终将以下内容添加到 package.json 中:
"homepage": "https://larkintuckerllc.github.io/hello-sentry/"
正在运行的应用程序的最终版本可在以下位置获取:
捕获的虫子的插图
让我们逐步了解如何单击“Hello”按钮。
出现这样的错误:
观察结果:
- 这个错误报告再清楚不过了, BRAVO.
未解释错误的说明
同样,让我们通过按钮单击 误差.
出现这样的错误:
更好地处理未解释的错误(渲染)
引入误差限
用户界面部分的 JavaScript 错误不应破坏整个应用程序。 为了为 React 用户解决这个问题,React 16 引入了一个名为“错误界限”的新概念。
错误边界是 React 组件,它可以捕获子组件树中任何位置的 JavaScript 错误,记录这些错误,并渲染后备 UI,而不是崩溃的组件树。 错误边界在渲染期间、生命周期方法以及其下方的整个树的构造函数中捕获错误。
...
针对未检测到的错误的新行为
这一变化意义重大。 从 React 16 开始,未被任何错误边界捕获的错误将导致整个 React 组件树被卸载。
- 丹·阿布拉莫夫 -
React 16 中的错误处理
我花了一段时间才意识到这一点的重要澄清是 上述行为仅适用于渲染方法中抛出的错误(或更可能在任何生命周期方法中)。 例如,使用错误边界对我们的按钮没有任何好处 误差; 此错误发生在点击处理程序中。
让我们创建一个示例渲染错误,然后使用错误边界更优雅地处理错误。
反应应用程序/src/MyRenderError
import React, { Component } from 'react';
export default class MyRenderError extends Component {
state = {
flag: false,
};
render() {
const { flag } = this.state;
return (
<div>
<button
onClick={this.handleClick}
>
Render Error
</button>
{ flag && <div>{flag.busted.bogus}</div> }
</div>
)
}
handleClick = () => {
this.setState({
flag: true,
});
}
}
观察:
-
当您按下按钮时, 应对 将显示 查获假旗,这会产生错误
-
如果没有错误边界,整个组件树将被卸载
然后我们编写错误边界代码(使用新的生命周期方法 组件DidCatch); 这本质上是 Dan Abramov 文章中给出的例子:
React-app/src/ErrorBoundary.js
import React, { Component } from 'react';
import * as Sentry from '@sentry/browser';
export default class ErrorBoundary extends Component {
constructor(props) {
super(props);
this.state = { hasError: false };
}
componentDidCatch(err, info) {
this.setState({ hasError: true });
Sentry.captureException(err);
}
render() {
if (this.state.hasError) {
return <h1>Something went wrong.</h1>;
}
return this.props.children;
}
}
最后我们使用这个组件:
反应应用程序/src/App.js
...
import MyRenderError from './MyRenderError';
class App extends Component {
render() {
return (
<ErrorBoundary>
<div className="App">
...
</div>
</ErrorBoundary>
);
}
}
...
但是,单击“渲染错误”按钮会显示后备 UI 并向 Sentry 报告错误。
完成
我希望您觉得这有帮助。
PS
通过 Sentry 进行 PS Telegram 聊天
来源: habr.com