Studiamo l'uso di Sentry con React.

Questo articolo fa parte di una serie che inizia con il messaggio di errore Sentry a titolo di esempio: .
Implementazione di React
Per prima cosa, dobbiamo aggiungere un nuovo progetto Sentry per questa applicazione; dal sito di Sentry. In questo caso, scegliamo React.
Implementiamo di nuovo i nostri due pulsanti, Hello ed Error, utilizzando React. Iniziamo creando la nostra applicazione di base:
npx create-react-app react-appPoi importiamo il pacchetto Sentry:
yarn add @sentry/browsere lo inizializziamo:
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,
});
}
...Osservazioni:
- Durante lo sviluppo abbiamo altri meccanismi per monitorare i problemi, ad esempio la console, quindi attiviamo Sentry solo per le build di produzione.
Poi implementiamo i nostri pulsanti Hello ed Error e li aggiungiamo all'applicazione:
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
...<br />import Hello from './Hello';<br />import MyError from './MyError';<br /><br />class App extends Component {<br /> render() {<br /> return (
<div classname="App">
...
<hello />
<myerror />
</div>
);<br /> }<br />}<br /><br />export default App;Problema (Sorgenti Mappa)
Possiamo testare Sentry con una build di produzione eseguendo:
yarn builde dalla cartella build eseguendo:
npx http-server -c-1Il problema con cui ci troveremo immediatamente è che le registrazioni degli errori di Sentry fanno riferimento ai numeri di riga nel pacchetto ridotto; non molto utile.

Il servizio Sentry spiega questo estraendo le mappe sorgente per il pacchetto ridotto dopo aver ricevuto l'errore. In questo caso, ci troviamo a correre da localhost (non accessibile dal servizio Sentry).
Soluzioni (Mappe Sorgente)
La soluzione a questo problema consiste nel lanciare l'applicazione da un server web pubblico. Un semplice pulsante di risposta sarebbe quello di utilizzare il servizio GitHub Pages (gratuito). I passaggi per l'uso sono solitamente i seguenti:
Copia il contenuto della cartella build nella cartella docs nella radice del repository.
Abilita GitHub Pages nel repository (da GitHub) per utilizzare la cartella docs in master branca
Spingi le modifiche su GitHub
Nota: dopo che ho capito di dover usare create-react-app la funzione homepage per lanciare l'applicazione. Si è trattato di aggiungere quanto segue a package.json:
"homepage": "https://larkintuckerllc.github.io/hello-sentry/"La versione finale dell'applicazione in esecuzione è disponibile all'indirizzo:
Illustrazione degli Errori Catturati
Facciamo clic sul pulsante Hello.

Con l'errore che appare nel seguente modo:

Osservazioni:
- Questa segnalazione di errore non potrebbe essere più chiara, BRAVO.
Illustrazione degli Errori Non Gestiti
Allo stesso modo, esaminiamo il clic sul pulsante Error.

Con l'errore che appare nel seguente modo:

La migliore gestione degli errori non gestiti (rendering)
Introduzione ai Limiti degli Errori
Un errore JavaScript nell'interfaccia utente non dovrebbe compromettere il funzionamento dell'intera applicazione. Per affrontare questo problema per gli utenti di React, React 16 introduce il nuovo concetto di "limiti degli errori".
I limiti degli errori sono componenti React che catturano errori JavaScript in qualsiasi parte del loro albero di componenti figli, registrano questi errori e visualizzano un'interfaccia utente di fallback invece dell'albero di componenti che si è guastato. I limiti degli errori catturano errori durante il rendering, nei metodi del ciclo di vita e nei costruttori di tutto l'albero sottostante.
…
Nuovo comportamento per errori non rilevati
Questa modifica è significativa. A partire da React 16, gli errori che non vengono catturati da alcun limite degli errori porteranno al disassemblaggio dell'intero albero dei componenti React.
— Dan Abramov —
Un'importante precisazione che mi ha richiesto un po' di tempo prima di comprendere è che il comportamento sopra menzionato funziona solo con gli errori generati nel metodo di rendering (o, più probabilmente, in uno qualsiasi dei metodi del ciclo di vita). Ad esempio, l'uso dei confini degli errori non sarebbe di alcuna utilità con il nostro pulsante Error; questo errore era nel gestore del clic.
Creiamo un esempio di errore di rendering e poi utilizziamo i confini degli errori per una gestione degli errori più elegante.
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}"
>
Errore di rendering
</button>
{ flag && <div>{flag.busted.bogus}</div> }
</div>
)
}
handleClick = () => {
this.setState({
flag: true,
});
}
}Osservazione:
Quando si preme il pulsante, React verrà visualizzato flag.busted.bogus, che genera un errore
Senza il confine degli errori, l'intero albero dei componenti verrà smontato
Poi scriviamo il nostro codice per il confine degli errori (usa il nuovo metodo del ciclo di vita componentDidCatch); questo è, in sostanza, un esempio fornito nell'articolo di 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>Qualcosa è andato storto.</h1>;
}
return this.props.children;
}
}Infine, utilizziamo questo componente:
react-app / src / App.js
...
import MyRenderError from './MyRenderError';
class App extends Component {
render() {
return (
<errorboundary>
<div classname="App">
...
</div>
</errorboundary>
);
}
}
...In questo modo, premendo il pulsante Render Error viene visualizzato un'interfaccia utente di riserva e viene segnalato l'errore a Sentry.


Conclusione
Spero che ti sia stato utile.
P.S.
P.S. Chat Telegram su Sentry
Fonte: habr.com
