Studiem utilizarea Sentry cu React.

Acest articol face parte dintr-o serie care începe cu raportarea erorilor Sentry exemplificată: .
Implementarea React
În primul rând, trebuie să adăugăm un nou proiect Sentry pentru această aplicație; de pe site-ul Sentry. În acest caz, alegem React.
Reimplementăm cele două butoane, Hello și Error, într-o aplicație React. Începem cu crearea aplicației noastre de bază:
npx create-react-app react-appApoi importăm pachetul Sentry:
yarn add @sentry/browserși îl inițializăm:
react-app / src / index.js
...
import * as Sentry from '@sentry/browser';
const RELEASE = '0.1.0';
if (process.env.NODE_ENV === 'production') {
Sentry.init({
dsn: 'https://303c04eac89844b5bfc908ceffc6757c@sentry.io/1289887',
release: RELEASE,
});
}
...Observații:
- În timpul dezvoltării, avem alte mecanisme pentru a monitoriza problemele, cum ar fi consola, deci activăm Sentry doar pentru compilările de producție.
Apoi implementăm butoanele Hello și Error și le adăugăm în aplicație:
react-app / 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);
}
}
}react-app / 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');
}
}react-app / 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;Problema (Hărți de origine)
Putem testa Sentry cu o compilare de producție, introducând:
yarn buildși din folderul build, introducem:
npx http-server -c-1Problema cu care ne confruntăm imediat este că înregistrările de erori Sentry se referă la numerele de linie din pachetul minimizat; nu este foarte util.

Serviciul Sentry explică acest lucru prin extragerea hărților de origine pentru pachetul minimizat după primirea unei erori. În acest caz, ne mișcăm de la localhost (inaccesibil pentru Sentry).
Soluții (Hărți de origine)
Soluția acestei probleme constă în a rula aplicația de pe un server web public. O simplă opțiune ar fi să folosim serviciul GitHub Pages (gratuit). Pașii sunt de obicei următorii:
Copiați conținutul folderului build în folderul docs în directorul rădăcină al repository-ului.
Activați GitHub Pages în repository (din GitHub) pentru a folosi folderul docs în master ramura
Transmiteți modificările pe GitHub
Notă: după ce am realizat că trebuie să folosesc create-create-app funcția homepage pentru a rula aplicația. A fost vorba de adăugarea următoarei linii în package.json:
"homepage": "https://larkintuckerllc.github.io/hello-sentry/"Versiunea finală a aplicației lansate este disponibilă la:
Ilustrarea Erorilor Capturate
Haideți să trecem prin apăsarea butonului Hello.

Cu eroarea apărând astfel:

Observații:
- Această raportare a erorii nu poate fi mai clară. BRAVO.
Ilustrarea Erorilor Neînregistrate
În mod similar, haideți să trecem prin apăsarea butonului Error.

Cu eroarea apărând astfel:

Cea mai bună gestionare a erorilor necontrolate (rendering)
Introducerea limitelor erorilor
O eroare JavaScript în partea de interfață utilizator nu ar trebui să afecteze funcționarea întregii aplicații. Pentru a rezolva această problemă pentru utilizatorii React, React 16 introduce un nou concept numit „limite ale erorilor”.
Limitele erorilor sunt componente React care prind erorile JavaScript din orice parte a arborelui lor de componente copil, înregistrează aceste erori și afișează o interfață utilizator rezervă în locul arborelui de componente care s-a defectat. Limitele erorilor prind erorile în timpul renderingului, în metodele ciclului de viață și în constructorii întregului arbore de sub ele.
…
Un comportament nou pentru erorile nedetectate
Această modificare este semnificativă. Începând cu React 16, erorile care nu sunt prinse de nicio limită a erorilor vor duce la demontarea întregului arbore de componente React.
— Dan Abramov —
O clarificare importantă, care mi-a luat ceva timp să o înțeleg, este că comportamentul menționat mai sus funcționează doar cu erorile generate în metoda de rendere (sau, mai probabil, în oricare dintre metodele ciclului de viață). De exemplu, utilizarea limitelor erorilor nu ar aduce niciun beneficiu cu butonul nostru Error; această eroare a fost în handlerul de click.
Să creăm un exemplu de eroare de vizualizare și apoi să folosim limitele erorilor pentru o gestionare mai elegantă a erorii.
react-app / 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}"
>
Eroare de redare
</button>
{ flag && <div>{flag.busted.bogus}</div> }
</div>
)
}
handleClick = () => {
this.setState({
flag: true,
});
}
}Observație:
Când apăsați butonul, React se va afișa flag.busted.bogus, care generează o eroare
Fără o limită de erori, întregul arbore de componente va fi demontat
Apoi scriem codul nostru pentru limita erorii (folosește noua metodă de ciclul de viață componentDidCatch); acesta este, practic, un exemplu dat în articolul lui 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>Ceva a mers prost.</h1>;
}
return this.props.children;
}
}În cele din urmă, folosim acest component:
react-app / src / App.js
...
import MyRenderError from './MyRenderError';
class App extends Component {
render() {
return (
<errorboundary>
<div classname="App">
...
</div>
</errorboundary>
);
}
}
...În acest fel, apăsarea butonului Render Error afișează o interfață utilizator rezervă și raportează eroarea Sentry.


Încheiere
Sper că ți-a fost de ajutor.
P.S.
P.S. Chat-ul Telegram despre Sentry
Sursa: habr.com
