Error Tracking in React Applications with Sentry

Error Tracking in React Applications with Sentry

Today, I will tell you about real-time error tracking in a React application. Front-end applications are typically not used for error tracking. Some companies often postpone error tracking, returning to it after documentation, testing, and more. However, if you can improve your product, just do it!

1. Why do you need Sentry?

I assume you are interested in tracking errors in a production environment.

Do you think that’s not enough?

Well, let’s look at the details.

Main reasons for developers to use Sentry:

  • Helps mitigate risks when deploying erroneous code.
  • Assists QA in testing the code.
  • Receives quick notifications about issues.
  • Allows for quick bug fixes.
  • Provides a convenient error display in the admin panel.
  • Sorts errors by user segments / browser.

Key reasons for CEOs / Project Leads.

  • Saves money (Sentry can be installed on your servers).
  • Collects user feedback.
  • Gains insight into what is wrong with your project in real-time.
  • Understands the number of problems users face with your application.
  • Helps identify areas where your developers made mistakes.

I believe developers would be most interested in this article. You can also use this list of reasons to convince management to integrate Sentry.

Be cautious with the last point on the list for businesses.

Are you already interested?

Error Tracking in React Applications with Sentry

What is Sentry?

Sentry is an open-source error tracking application that helps developers monitor and fix crashes in real-time. Remember that the application also enhances efficiency and improves user experience. Sentry supports JavaScript, Node, Python, PHP, Ruby, Java, and other programming languages.

Error Tracking in React Applications with Sentry

2. Log in and create a project.

  • Open your Sentry account. You may need to log in. (Note that Sentry can be installed on your servers.)
  • The next step is to create a project.
  • Select your language from the list. (We are going to choose React. Click 'Create Project')

Error Tracking in React Applications with Sentry

Set up your application. A basic example of how to integrate Sentry into a container can be seen below:

import * as Sentry from '@sentry/browser';
// Sentry.init({
//   dsn: "<https:>"
// });
// should have been called before using it here
// ideally before even rendering your react app 

class ExampleBoundary extends Component {
    constructor(props) {
        super(props);
        this.state = { error: null };
    }

    componentDidCatch(error, errorInfo) {
      this.setState({ error });
      Sentry.withScope(scope =&gt; {
        Object.keys(errorInfo).forEach(key =&gt; {
          scope.setExtra(key, errorInfo[key]);
        });
        Sentry.captureException(error);
      });
    }

    render() {
        if (this.state.error) {
            // render fallback UI
            return (
              <a onclick="{()" > Sentry.showReportDialog()}&gt;Report feedback</a>
            );
        } else {
            // when there's not an error, render children untouched
            return this.props.children;
        }
    }
}

Sentry has a helpful Wizard that will guide you on what to do next. You can follow these steps. I want to show you how to create your first error handler. Great, we've set up a project! Let's move on to the next step.

3. Integrating React and Sentry

You need to install the npm package in your project.

npm i @sentry/browser

Initialize Sentry in your container:

Sentry.init({
 // dsn: #dsnUrl,
});

The DSN is located in Projects -> Settings -> Client Keys. You can find client keys in the search bar.

Error Tracking in React Applications with Sentry

componentDidCatch(error, errorInfo) {
  Sentry.withScope(scope => {
    Object.keys(errorInfo).forEach(key => {
      scope.setExtra(key, errorInfo[key]);
    });
    Sentry.captureException(error);
 });
}

4. Tracking the First Error

For example, I used a simple music application with the Deezer API. You can see it. here. We need to create an error. One way to do this is to access a property of 'undefined'.

We need to create a button that calls console.log with user.email. After this action, we should see an error message: Uncaught TypeError (cannot read property of undefined email) because the user object is missing. You can also use Javascript exception.

The entire container looks like this:

import React, { Component } from "react";
import { connect } from "react-redux";
import { Input, List, Skeleton, Avatar } from "antd";
import * as Sentry from "@sentry/browser";
import getList from "..\/store\/actions\/getList";

const Search = Input.Search;

const mapState = state =&gt; ({
  list: state.root.list,
  loading: state.root.loading
});

const mapDispatch = {
  getList
};

class Container extends Component {
  constructor(props) {
    super(props);

    Sentry.init({
      dsn: "https:\/\/fc0edcf6927a4397855797a033f04085@sentry.io\/1417586",
    });
  }

  componentDidCatch(error, errorInfo) {
    Sentry.withScope(scope =&gt; {
      Object.keys(errorInfo).forEach(key =&gt; {
        scope.setExtra(key, errorInfo[key]);
      });
      Sentry.captureException(error);
    });
  }
  render() {
    const { list, loading, getList } = this.props;
    const user = undefined;
    return (
      <div classname="App">
        <button
          type="button"
          onclick="{()" > console.log(user.email)}
        &gt;
          test error1
        </button>
        <div onclick="{()" > Sentry.showReportDialog()}&gt;Report feedback1</div>
        <h1>Music Finder</h1>
        <br />
        <search onsearch="{value" > getList(value)} enterButton \/&gt;
        {loading &amp;&amp; <skeleton avatar title="{false}" loading="{true}" active />}
        {!loading &amp;&amp; (
          <list
            itemlayout="horizontal"
            datasource="{list}"
            locale="{{" emptytext: <div /> }}
            renderItem={item =&gt; (
              <List.Item>
                &lt;List.Item.Meta
                  avatar={<avatar src="{item.artist.picture}" />}
                  title={item.title}
                  description={item.artist.name}
                \/&gt;
              </List.Item>
            )}
          />
        )}
      </div>
    );
  }
}

export default connect(
  mapState,
  mapDispatch
)(Container);

After integrating this button, you should test it in your browser.

Error Tracking in React Applications with Sentry

We have our first error

Error Tracking in React Applications with Sentry

Whoo-hoo!

Error Tracking in React Applications with Sentry

If you click on the error header, you will see a stack trace.

Error Tracking in React Applications with Sentry

The messages look bad. Of course, we saw error messages without understanding where this code is. By default, it refers to the source map in ReactJS, as they are not configured.

I would also like to provide instructions on setting up the source map, but that would make this article much longer than I intended.

You can explore this topic here. If you are interested in this article, Dmitry Nozhenko will publish a second part on integrating the source map. So make sure to like and subscribe Dmitry Nozhenko, so you don't miss the second part.

5. Using Sentry the endpoint API

Okay. We've covered the JavaScript exception in the previous sections. However, what are we going to do with XHR errors?

Sentry also has custom error handling. I've used it for tracking API errors.

Sentry.captureException(err)

You can customize the error name, level, add data, unique user data using your application, email, etc.

superagent
  .get(`https://deezerdevs-deezer.p.rapidapi.com/search?q=${query}`)
  .set("X-RapidAPI-Key", #id_key)
  .end((err, response) => {
    if (err) {
      Sentry.configureScope(
        scope => scope
          .setUser({"email": "john.doe@example.com"})
          .setLevel("Error")
      );
      return Sentry.captureException(err);
    }

    if (response) {
      return dispatch(setList(response.body.data));
    }
  });

I would like to use a common function for API catch.

import * as Sentry from "@sentry/browser";

export const apiCatch = (error, getState) => {
  const store = getState();
  const storeStringify = JSON.stringify(store);
  const { root: { user: { email } } } = store;

  Sentry.configureScope(
    scope => scope
      .setLevel("Error")
      .setUser({ email })
      .setExtra("store", storeStringify)
  );
    // Sentry.showReportDialog(); - If you want to get users' feedback on error
  return Sentry.captureException(error);
};

Import this function into the API call.

export default query => (dispatch, getState) => {
  superagent
    .get(`https://deezerdevs-deezer.p.rapidapi.com/search?q=${query}`)
    .set("X-RapidAPI-Key", #id_key)
    .end((error, response) => {
      if (error) {
        return apiCatch(error, getState)
      }

      if (response) {
        return dispatch(setList(response.body.data));
      }
    });
};

Let's check the methods:

  • setLevel allows you to insert a level error into the Sentry dashboard. It has properties - ‘fatal’, ‘error’, ‘warning’, ‘log’, ‘info’, ‘debug’, ‘critical’).
  • setUser helps save any user data (id, email address, payment plan, etc.).
  • setExtra allows you to set any data you need, such as the store.

If you want to receive user feedback on an error, you should use the showReportDialog function.

Sentry.showReportDialog();

Output:

Today we described one way to integrate Sentry into a React application.

→ Telegram chat about Sentry

Source: habr.com

Buy reliable website hosting with DDoS protection, VPS VDS servers 🔥 Buy reliable website hosting with DDoS protection, VPS VDS servers | ProHoster