Suivi des erreurs dans une application React avec Sentry



Aujourd'hui, je vais vous expliquer le suivi des erreurs en temps réel dans une application React. Une application frontale n'est généralement pas utilisée pour le suivi des bogues. Certaines entreprises reportent souvent le suivi des bogues en y revenant après la documentation, les tests, etc. Cependant, si vous pouvez améliorer votre produit, faites-le!



1. Pourquoi avez-vous besoin de Sentry?



Je suppose que vous êtes intéressé par le suivi des bogues pendant la production



Pensez-vous que cela ne suffit pas?



Ok, voyons les détails.



Principales raisons d'utiliser Sentry pour les développeurs:



  • Élimine le risque de déploiement de code bogué
  • Assistance QA dans les tests de code
  • Recevez des notifications rapides des problèmes
  • La possibilité de corriger rapidement les erreurs
  • Obtenir un affichage pratique des erreurs dans le panneau d'administration
  • Tri des erreurs par segment utilisateur / navigateur


Les principales raisons du PDG / Chef de projet



  • Économiser de l'argent (Sentry peut être installé sur vos serveurs)
  • Obtenir les commentaires des utilisateurs
  • Compréhension en temps réel de ce qui ne va pas avec votre projet
  • Comprendre le nombre de problèmes rencontrés par les utilisateurs avec votre application
  • Aidez à trouver les endroits où vos développeurs ont commis une erreur


, . , Sentry.



.



?





Sentry?



Sentry – , , . , . Sentry JavaScript, Node, Python, PHP, Ruby, Java .





2.



  • Sentry . , . ( Sentry )
  • . ( React. « »)




. , Sentry , :



import * as Sentry from '@sentry/browser';
// Sentry.init({
//  dsn: "<https://63bbb258ca4346139ee533576e17ac46@sentry.io/1432138>"
// });
// 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 => {
        Object.keys(errorInfo).forEach(key => {
          scope.setExtra(key, errorInfo[key]);
        });
        Sentry.captureException(error);
      });
    }

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


Sentry , , . . , . , !



3. React Sentry



npm .



npm i @sentry/browser


Sentry :



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


DSN Projects -> Settings -> Client Keys. .





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


4.



API Deezer. . . "undefined"



, console.log user.email. : Uncaught TypeError ( email) - . Javascript.



<button type="button" onClick={() => console.log(user.email)}>   
  Test Error button 
</button>


:



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 => ({
  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 => {
      Object.keys(errorInfo).forEach(key => {
        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)}
        >
          test error1
        </button>
        <div onClick={() => Sentry.showReportDialog()}>Report feedback1</div>
        <h1>Music Finder</h1>
        <br />
        <Search onSearch={value => getList(value)} enterButton />
        {loading && <Skeleton avatar title={false} loading={true} active />}
        {!loading && (
          <List
            itemLayout="horizontal"
            dataSource={list}
            locale={{ emptyText: <div /> }}
            renderItem={item => (
              <List.Item>
                <List.Item.Meta
                  avatar={<Avatar src={item.artist.picture} />}
                  title={item.title}
                  description={item.artist.name}
                />
              </List.Item>
            )}
          />
        )}
      </div>
    );
  }
}

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


.









Whoo-hoo!





, .





. , , , . ReactJS, .



, , .



. , Dmitry Nozhenko source map. , Dmitry Nozhenko, .



5. Sentry API



. javascript . , XHR?



Sentry . api.



Sentry.captureException(err)


, , , , . .



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));
    }
  });


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 get users feedback on error
  return Sentry.captureException(error);
};


api.



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));
      }
    });
};


:



  • setLevel sentry. — ‘fatal’, ‘error’, ‘warning’, ‘log’, ‘info, ‘debug’, ‘critical’).
  • setUser (id, , . .).
  • setExtra , , , .


Si vous souhaitez obtenir les commentaires des utilisateurs sur un bogue, vous devez utiliser la fonction showReportDialog.



Sentry.showReportDialog();


Production:



Aujourd'hui, nous avons décrit une façon d'intégrer Sentry dans une application React.



→ Chat télégramme via Sentry




All Articles