Sentry Error Reporting By Example: Part 2

We explore using Sentry with React.

Image for post
Image for post

This article is part of the series starting with Sentry Error Reporting By Example: Part 1.

React Implementation

We first need to add a new Sentry project for this application; from the Sentry site. In this case, we select React.

We re-implement our two button, Hello and Error, application with React. We start by generating our starting application:

npx create-react-app react-app

We then import the Sentry package:

yarn add @sentry/browser

and initialize it:

react-app / src / index.js

Observations:

  • During development, we have other mechanisms to observe problems, e.g., the console, so we only enable Sentry for production builds

We then implement our Hello and Error buttons and add it to the application:

react-app / src / Hello.js

react-app / src / MyError.js

react-app / src / App.js

A Problem (Source Maps)

We can test Sentry with a production build by entering:

yarn build

and from the build folder enter:

npx http-server -c-1

The problem that we will immediately encounter is that the Sentry error entries refer to line numbers in the minified bundle; not terribly useful.

Image for post
Image for post

The Sentry service accounts for this by pulling the source maps for the minified bundle after receiving the error. In this case, we are running from localhost (not accessible by the Sentry service).

Solved (Source Maps)

The solution to this problem amounts to running the application from a publicly accessible web server. One easy-button answer it to use the GitHub Pages service (free). The steps to use are generally:

  1. Copy the contents of the build folder to a docs folder in the root of the repository.
  2. Enable GitHub Pages on the repository (from GitHub) to use the docs folder in the master branch
  3. Push the changes to GitHub

note: After-the-fact, I realized that I needed to use the create-create-app homepage feature to get the application to run. Amounted to adding the following to package.json: “homepage”: “https://larkintuckerllc.github.io/hello-sentry/"

The final version of the running application is available at: https://larkintuckerllc.github.io/hello-sentry/

Illustrating Caught Errors

Let us walk through clicking the Hello button.

Image for post
Image for post

With the error appearing as follows:

Image for post
Image for post

Observations:

  • This error report could not be more clear, BRAVO.

Illustrating Uncaught Errors

Likewise, let us walk through clicking the Error button.

Image for post
Image for post

With the error appearing as follows:

Image for post
Image for post

Better Handling of Uncaught (Render) Errors

Introducing Error Boundaries
A JavaScript error in a part of the UI shouldn’t break the whole app. To solve this problem for React users, React 16 introduces a new concept of an “error boundary”.

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 crashed. Error boundaries catch errors during rendering, in lifecycle methods, and in constructors of the whole tree below them.

New Behavior for Uncaught Errors
This change has an important implication. As of React 16, errors that were not caught by any error boundary will result in unmounting of the whole React component tree.

Dan Abramov — Error Handling in React 16

The important clarification, took me some time before I realized this, is that the aforementioned behavior only works with errors generated in a render method (or more likely in any of the lifecycle methods). For example, using error boundaries would have no benefit with our Error button; that error was in a click handler.

Let us create a render error example and then use error boundaries to more gracefully handle the error.

react-app / src / MyRenderError

Observation:

  • When the button is clicked, React will attempt to render flag.busted.bogus which generates an error
  • Without an error boundary, the entire component tree will unmount

We then write our error boundary code (uses the new life-cycle method componentDidCatch); this is essentially the example provided in Dan Abramov’s article:

react-app / src / ErrorBoundary.js

Finally, we use this component:

react-app / src / App.js

With this in place, clicking the Render Error button displays the fall back UI and reports the error to Sentry.

Image for post
Image for post
Image for post
Image for post

Wrap Up

Hope you found this useful.

Written by

Broad infrastructure, development, and soft-skill background

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store