We can test Sentry with a production build by typing:
yarn build
and from build folder type:
npx http-server -c-1
The problem we immediately run into is that the Sentry error entries refer to line numbers in the reduced package; not very helpful.
The Sentry service explains this by pulling the source maps for the reduced batch after receiving an error. In this case, we are running from localhost (not accessible by the Sentry service).
Solutions (Source Maps)
The solution to this problem is to run the application from a public web server. One simple answer button to use the GitHub Pages service (free). The steps to use are usually the following:
Copy the contents of the folder build to folder docs in the root directory of the repository.
Turn on GitHub Pages in the repository (from GitHub) to use the docs folder in master vetvi
Push changes to GitHub
Note: after I figured out what I need to use create-create-app home page function to launch the application. It boiled down to adding the following to package.json:
Likewise, let's go through the button press Error.
With an error appearing like this:
Better unhandled error handling (rendering)
Introduction of Error Boundaries
A JavaScript error in the user interface should not break the entire application. To solve this problem for React users, React 16 introduces a new concept of "error border".
Error boundaries are React components that catch JavaScript errors anywhere in their child component tree, log those errors, and display a fallback UI instead of the component tree that has crashed. Error boundaries catch errors at render time, in lifecycle methods, and in the constructors of the entire tree below them.
...
New behavior for undetected errors
This change is important. As of React 16, errors that are not caught by any error boundary will cause the entire React component tree to be unmounted.
An important clarification, which took me a while before I figured it out, is that the above behavior only works with errors thrown in the render method (or more likely any of the lifecycle methods). For example, using error borders wouldn't do any good with our button Error; this error was in the click handler.
Let's create an example render error and then use error bounds to handle the error more gracefully.
When you press the button, React will be displayed flag.busted.bogus, which generates an error
Without an error boundary, the entire component tree will be unmounted
We then write our error boundary code (uses the new lifecycle method componentDidCatch); this is essentially the example given in Dan Abramov's article:
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;
}
}