Estamos explorando el uso de Sentry con React.

Este artículo es parte de una serie que comienza con un informe de errores de Sentry utilizando: .
Implementación de React
Primero necesitamos agregar un nuevo proyecto Sentry para esta aplicación desde el sitio web de Sentry. En este caso, elegimos React.
Volvemos a implementar nuestros dos botones, Hello y Error, en la aplicación React. Comenzamos creando nuestra aplicación inicial:
npx create-react-app react-appLuego importamos el paquete Sentry:
yarn add @sentry/browsery lo inicializamos:
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,
});
}
...Observaciones:
- Durante el desarrollo, tenemos otros mecanismos para observar problemas, como la consola, por lo que solo activamos Sentry para las compilaciones de producción.
Luego implementamos nuestros botones Hello y Error y los añadimos a la aplicación:
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}"
>
Hola
</button>
<div>{text}</div>
</div>
)
}
handleClick = () => {
this.setState({
text: 'Hola Mundo',
});
try {
throw new Error('Capturado');
} 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 (Mapas de Origen)
Podemos probar Sentry con una compilación de producción ingresando:
yarn buildy desde la carpeta build, ingresamos:
npx http-server -c-1El problema con el que nos enfrentaremos de inmediato es que los registros de errores de Sentry hacen referencia a números de línea en el paquete minimizado; no es muy útil.

El servicio Sentry explica esto obteniendo los mapas de origen para el paquete minimizado después de recibir el error. En este caso, estamos corriendo desde localhost (no accesible por Sentry).
Soluciones (Mapas de Origen)
La solución a este problema implica ejecutar la aplicación desde un servidor web público. Una opción sencilla es utilizar el servicio Pages de GitHub (gratis). Los pasos para utilizarlo generalmente son los siguientes:
Copie el contenido de la carpeta build a la carpeta docs en la raíz del repositorio.
Habilite GitHub Pages en el repositorio (desde GitHub) para usar la carpeta docs en master la rama
Suba los cambios a GitHub
Nota: después de darme cuenta de que necesitaba usar create-create-app la función homepage para lanzar la aplicación. Se redujo a agregar lo siguiente a package.json:
"homepage": "https://larkintuckerllc.github.io/hello-sentry/"La versión final de la aplicación en ejecución está disponible en:
Ilustración de Errores Capturados
Vamos a revisar lo que sucede al presionar el botón Hello.

Con el error apareciendo de la siguiente manera:

Observaciones:
- Este informe de error no podría ser más claro, ¡BRAVO!.
Ilustración de Errores No Capturados
De manera similar, vamos a revisar lo que sucede al presionar el botón. Error.

Con el error apareciendo de la siguiente manera:

La mejor gestión de errores no capturados (renderizado)
Introducción a los Límites de Errores
Un error de JavaScript en una parte de la interfaz de usuario no debería interrumpir el funcionamiento de toda la aplicación. Para resolver este problema para los usuarios de React, React 16 introduce el nuevo concepto de "límites de errores".
Los límites de errores son componentes de React que atrapan errores de JavaScript en cualquier parte de su árbol de componentes hijo, registran esos errores y muestran una interfaz de usuario de reserva en lugar del árbol de componentes que se rompió. Los límites de errores capturan errores durante el renderizado, en los métodos del ciclo de vida y en los constructores de todo el árbol debajo de ellos.
…
Nuevo comportamiento para errores no detectados
Este cambio es significativo. A partir de React 16, los errores que no sean capturados por ningún límite de errores resultarán en el desmontaje de todo el árbol de componentes de React.
— Dan Abramov —
Una aclaración importante que me llevó un tiempo entender es que el comportamiento mencionado anteriormente solo funciona con errores generados en el método de renderizado (o, más probablemente, en cualquiera de los métodos del ciclo de vida). Por ejemplo, usar límites de errores no sería útil con nuestro botón Error; este error estaba en el controlador de clics.
Creemos un ejemplo de error de visualización y luego usemos límites de errores para una gestión de errores más 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}"
>
Error de renderizado
</button>
{ flag && <div>{flag.busted.bogus}</div> }
</div>
)
}
handleClick = () => {
this.setState({
flag: true,
});
}
}Observación:
Al hacer clic en el botón, React se mostrará flag.busted.bogus, que genera un error
Sin límite de errores, todo el árbol de componentes se desmontará.
Luego, escribimos nuestro código de límite de errores (utiliza el nuevo método del ciclo de vida componentDidCatch); este es esencialmente el ejemplo proporcionado en el artículo de 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>Algo salió mal.</h1>;
}
return this.props.children;
}
}Finalmente, usamos este componente:
react-app / src / App.js
...\nimport MyRenderError from './MyRenderError';\n\nclass App extends Component {\n render() {\n return (
<errorboundary>
<div classname="App">
...
</div>
</errorboundary>
);
}
}
...Así, al hacer clic en el botón Render Error se muestra la interfaz de usuario de reserva y se informa del error a Sentry.


Conclusión
Espero que te haya sido útil.
P.D.
P.S. Chat de Telegram sobre Sentry
Fuente: habr.com
