我們正在探索將 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,
});
}
}
觀察:
-
當您按下按鈕時, 應對 將顯示 查獲假旗,這會產生錯誤
-
如果沒有錯誤邊界,整個元件樹將被卸載
然後我們編寫錯誤邊界程式碼(使用新的生命週期方法 組件捕獲); 這本質上是 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 報告錯誤。
完成
我希望您覺得這有幫助。
聚苯乙烯
透過 Sentry 進行 PS Telegram 聊天
來源: www.habr.com