We onderzoeken het gebruik van Sentry met React.

Dit artikel maakt deel uit van een serie die begint met een foutmelding in Sentry aan de hand van een voorbeeld: .
Implementatie van React
Eerst moeten we een nieuw Sentry-project toevoegen voor deze applicatie; vanaf de Sentry-website. In dit geval kiezen we voor React.
We implementeren opnieuw onze twee knoppen, Hello en Error, in de React-app. We beginnen met het maken van onze startapplicatie:
npx create-react-app react-appDaarna importeren we het Sentry-pakket:
yarn add @sentry/browseren initialiseren we het:
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,
});
}
...Observaties:
- Tijdens de ontwikkeling hebben we andere mechanismen voor het observeren van problemen, zoals de console, dus we schakelen Sentry alleen in voor productie-uitvoeringen.
Daarna implementeren we onze knoppen Hello en Error en voegen ze toe aan de app:
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}"
>
Hallo
</button>
<div>{text}</div>
</div>
)
}
handleClick = () => {
this.setState({
text: 'Hallo Wereld',
});
try {
throw new Error('Vang');
} 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}"
>
Fout
</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;Probleem (Bronkaarten)
We kunnen Sentry testen met een productie-uitvoering door het volgende in te voeren:
yarn builden in de build-map voeren we in:
npx http-server -c-1Het probleem dat we direct tegenkomen, is dat de foutmeldingen van Sentry verwijzen naar regelnummers in het verkleinde pakket; niet erg handig.

De service Sentry legt dit uit door de bron kaarten voor het verkleinde pakket op te halen nadat een fout is opgetreden. In dit geval lopen we van localhost (niet bereikbaar voor de Sentry-service).
Oplossingen (Bronkaarten)
Het oplossen van dit probleem komt neer op het draaien van de applicatie vanaf een openbare webserver. Een eenvoudige oplossing is om de GitHub Pages-service (gratis) te gebruiken. De stappen om dit meestal te doen zijn als volgt:
Kopieer de inhoud van de map build kopiëren naar de map docs in de hoofdmap van de repository.
Schakel GitHub Pages in de repository (vanuit GitHub) in om de docs-map te gebruiken in master de tak
Verplaats de wijzigingen naar GitHub
Opmerking: nadat ik begrijp dat ik de create-create-app homepage-functie moest gebruiken om de applicatie te draaien. Dit kwam neer op het toevoegen van het volgende aan package.json:
"homepage": "https://larkintuckerllc.github.io/hello-sentry/"De definitieve versie van de draaiende applicatie is beschikbaar op:
Illustratie van gevangen fouten
Laten we het proces doorlopen bij het drukken op de Hello-knop.

Met de fout die als volgt verschijnt:

Observaties:
- Dit foutrapport kan niet duidelijker zijn, BRAVO.
Illustratie van niet-gevangen fouten
Evenzo, laten we het proces doorlopen bij het drukken op de knop Fout.

Met de fout die als volgt verschijnt:

De beste behandeling van niet-gehandleerde fouten (rendering)
Inleiding tot foutgrenzen
Een JavaScript-fout in een deel van de gebruikersinterface mag de werking van de hele applicatie niet verstoren. Om dit probleem voor React-gebruikers op te lossen, introduceert React 16 het nieuwe concept van "foutgrenzen".
Foutgrenzen zijn React-componenten die JavaScript-fouten opvangen waar dan ook in hun kindcomponenten, deze fouten registreren en een reservegebruikersinterface weergeven in plaats van de gebroken componentenboom. Foutgrenzen vangen fouten op tijdens het renderen, in levenscyclusmethoden en in constructeurs van de hele boom onder hen.
…
Nieuw gedrag voor niet-opgevangen fouten
Deze wijziging is van cruciaal belang. Vanaf React 16 zullen fouten die door geen enkele foutgrens zijn opgevangen, leiden tot het demonteren van de hele React-componentenboom.
— Dan Abramov —
Een belangrijke nuance die enige tijd kostte voordat ik het begreep, is dat het hierboven beschreven gedrag alleen werkt met fouten die worden gegenereerd in de render-methode (of, waarschijnlijker, in een van de levenscyclusmethoden). Bijvoorbeeld, het gebruik van foutgrenzen zou ons geen voordelen hebben opgeleverd met onze knop Fout; deze fout zat in de klikhandler.
Laten we een voorbeeld van een renderfout maken, en daarna foutgrenzen gebruiken voor een elegantere foutafhandeling.
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}"
>
Render Fout
</button>
{ flag && <div>{flag.busted.bogus}</div> }
</div>
)
}
handleClick = () => {
this.setState({
flag: true,
});
}
}Opmerking:
Bij het klikken op de knop, React dezelfde indicatie van een beveiligde verbinding worden weergegeven als voor certificaten met domeinverificatie. flag.busted.bogus, die een fout genereert
Zonder een foutgrens zal de hele componentenboom worden gedemonteerd.
Dan schrijven we onze foutgrenscode (maakt gebruik van de nieuwe levenscyclusmethode componentDidCatch); dit is in wezen een voorbeeld dat in het artikel van Dan Abramov wordt gegeven:
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>Er is iets misgegaan.</h1>;
}
return this.props.children;
}
}Ten slotte gebruiken we deze component:
react-app / src / App.js
...
import MyRenderError from './MyRenderError';
class App extends Component {
render() {
return (
<errorboundary>
<div classname="App">
...
</div>
</errorboundary>
);
}
}
...Hierdoor zal het klikken op de knop Render Error de reservegebruikersinterface weergeven en een fout melden aan Sentry.


Afsluiting
Ik hoop dat je dit nuttig vond.
P.S.
P.S. Telegram-chat over Sentry
Bron: habr.com
