рд╕реЗрдиреНрдЯреНрд░реА рдкреНрд░рдпреЛрдЧ рдЧрд░реЗрд░ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдЕрдиреБрдкреНрд░рдпреЛрдЧрдорд╛ рдЯреНрд░реНрдпрд╛рдХрд┐рдЩ рддреНрд░реБрдЯрд┐рд╣рд░реВ

рд╕реЗрдиреНрдЯреНрд░реА рдкреНрд░рдпреЛрдЧ рдЧрд░реЗрд░ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдЕрдиреБрдкреНрд░рдпреЛрдЧрдорд╛ рдЯреНрд░реНрдпрд╛рдХрд┐рдЩ рддреНрд░реБрдЯрд┐рд╣рд░реВ

рдЖрдЬ рдо рддрдкрд╛рдИрдВрд▓рд╛рдИ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдЕрдиреБрдкреНрд░рдпреЛрдЧрдорд╛ рд╡рд╛рд╕реНрддрд╡рд┐рдХ-рд╕рдордп рддреНрд░реБрдЯрд┐ рдЯреНрд░реНрдпрд╛рдХрд┐рдЩрдХреЛ рдмрд╛рд░реЗрдорд╛ рдмрддрд╛рдЙрдиреЗрдЫреБред рдлреНрд░рдиреНрдЯ-рдПрдиреНрдб рдЕрдиреБрдкреНрд░рдпреЛрдЧ рд╕рд╛рдорд╛рдиреНрдпрддрдпрд╛ рддреНрд░реБрдЯрд┐ рдЯреНрд░реНрдпрд╛рдХрд┐рдЩрдХреЛ рд▓рд╛рдЧрд┐ рдкреНрд░рдпреЛрдЧ рдЧрд░рд┐рдБрджреИрдиред рдХреЗрд╣реА рдХрдореНрдкрдиреАрд╣рд░реВрд▓реЗ рдкреНрд░рд╛рдпрдГ рдмрдЧ рдЯреНрд░реНрдпрд╛рдХрд┐рдЩ рдмрдиреНрдж рд░рд╛рдЦреНрдЫрдиреН, рдХрд╛рдЧрдЬрд╛рддрд╣рд░реВ, рдкрд░реАрдХреНрд╖рдгрд╣рд░реВ, рдЗрддреНрдпрд╛рджрд┐ рдкрдЫрд┐ рдпрд╕рдорд╛ рдлрд░реНрдХрдиреНрдЫрдиреНред рдпрджреНрдпрдкрд┐, рдпрджрд┐ рддрдкрд╛рдЗрдБ рдЖрдлреНрдиреЛ рдЙрддреНрдкрд╛рджрдирд▓рд╛рдИ рд░рд╛рдореНрд░реЛрдХреЛ рд▓рд╛рдЧрд┐ рдкрд░рд┐рд╡рд░реНрддрди рдЧрд░реНрди рд╕рдХреНрдиреБрд╣реБрдиреНрдЫ рднрдиреЗ, рддреНрдпрд╕реЛ рдЧрд░реНрдиреБрд╣реЛрд╕реН!

1. рддрдкрд╛рдИрд▓рд╛рдИ рдХрд┐рди рд╕реЗрдиреНрдЯреНрд░реА рдЪрд╛рд╣рд┐рдиреНрдЫ?

рдо рдЕрдиреБрдорд╛рди рдЧрд░реНрдЫреБ рдХрд┐ рддрдкрд╛рдИ рдЙрддреНрдкрд╛рджрдирдХреЛ рдХреНрд░рдордорд╛ рдмрдЧрд╣рд░реВ рдЯреНрд░реНрдпрд╛рдХ рдЧрд░реНрдирдорд╛ рд░реБрдЪрд┐ рд░рд╛рдЦреНрдиреБрд╣реБрдиреНрдЫ

рдХреЗ рддрдкрд╛рдИрд▓рд╛рдИ рдпреЛ рдкрд░реНрдпрд╛рдкреНрдд рдЫреИрди рдЬрд╕реНрддреЛ рд▓рд╛рдЧреНрдЫ?

рдареАрдХ рдЫ, рд╡рд┐рд╡рд░рдгрд╣рд░реВ рд╣реЗрд░реМрдВред

рд╡рд┐рдХрд╛рд╕рдХрд░реНрддрд╛рд╣рд░реВ рд╕реЗрдиреНрдЯреНрд░реА рдкреНрд░рдпреЛрдЧ рдЧрд░реНрдирдХрд╛ рд▓рд╛рдЧрд┐ рд╢реАрд░реНрд╖ рдХрд╛рд░рдгрд╣рд░реВ:

  • рддреНрд░реБрдЯрд┐рд╣рд░реВрд╕рдБрдЧ рдХреЛрдб рдбрд┐рдкреНрд▓реЛрдЗ рдЧрд░реНрджрд╛ рддрдкрд╛рдИрдВрд▓рд╛рдИ рдЬреЛрдЦрд┐рдорд╣рд░реВрдмрд╛рдЯ рдмрдЪреНрди рдЕрдиреБрдорддрд┐ рджрд┐рдиреНрдЫ
  • рдХреЛрдб рдкрд░реАрдХреНрд╖рдгрдХреЛ рд╕рд╛рде QA рдорджреНрджрдд рдЧрд░реНрдиреБрд╣реЛрд╕реН
  • рд╕рдорд╕реНрдпрд╛рд╣рд░реВрдХреЛ рдмрд╛рд░реЗрдорд╛ рджреНрд░реБрдд рд╕реВрдЪрдирд╛рд╣рд░реВ рдкреНрд░рд╛рдкреНрдд рдЧрд░реНрдиреБрд╣реЛрд╕реН
  • рддреНрд░реБрдЯрд┐рд╣рд░реВ рдЫрд┐рдЯреЛ рд╕рдЪреНрдпрд╛рдЙрди рд╕рдХреНрдиреЗ рдХреНрд╖рдорддрд╛
  • рдкреНрд░рд╢рд╛рд╕рдХ рдкреНрдпрд╛рдирд▓рдорд╛ рддреНрд░реБрдЯрд┐рд╣рд░реВрдХреЛ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рдкреНрд░рджрд░реНрд╢рди рдкреНрд░рд╛рдкреНрдд рдЧрд░реНрджреИ
  • рдкреНрд░рдпреЛрдЧрдХрд░реНрддрд╛/рдмреНрд░рд╛рдЙрдЬрд░ рдЦрдгреНрдб рдЕрдиреБрд╕рд╛рд░ рддреНрд░реБрдЯрд┐рд╣рд░реВ рдХреНрд░рдордмрджреНрдз рдЧрд░реНрдиреБрд╣реЛрд╕реН

рд╕реАрдИрдУ/рд▓реАрдб рдкреНрд░реЛрдЬреЗрдХреНрдЯрдХреЛ рдореБрдЦреНрдп рдХрд╛рд░рдгрд╣рд░реВ

  • рдкреИрд╕рд╛ рдмрдЪрдд рдЧрд░реНрдиреБрд╣реЛрд╕реН (рд╕реЗрдиреНрдЯреНрд░реА рддрдкрд╛рдИрдВрдХреЛ рд╕рд░реНрднрд░рдорд╛ рд╕реНрдерд╛рдкрдирд╛ рдЧрд░реНрди рд╕рдХрд┐рдиреНрдЫ)
  • рдкреНрд░рдпреЛрдЧрдХрд░реНрддрд╛ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдкреНрд░рд╛рдкреНрдд рдЧрд░реНрджреИ
  • рд╡рд╛рд╕реНрддрд╡рд┐рдХ рд╕рдордпрдорд╛ рддрдкрд╛рдИрдВрдХреЛ рдкрд░рд┐рдпреЛрдЬрдирд╛рдорд╛ тАЛтАЛрдХреЗ рдЧрд▓рдд рдЫ рдмреБрдЭреНрджреИ
  • рддрдкрд╛рдИрдВрдХреЛ рдПрдкрдорд╛ рдорд╛рдирд┐рд╕рд╣рд░реВрд▓рд╛рдИ рд╣реБрдиреЗ рд╕рдорд╕реНрдпрд╛рд╣рд░реВрдХреЛ рд╕рдЩреНрдЦреНрдпрд╛ рдмреБрдЭреНрджреИ
  • рддрдкрд╛рдИрдВрдХрд╛ рд╡рд┐рдХрд╛рд╕рдХрд░реНрддрд╛рд╣рд░реВрд▓реЗ рдЧрд▓реНрддреА рдЧрд░реЗрдХреЛ рдард╛рдЙрдБрд╣рд░реВ рдлреЗрд▓рд╛ рдкрд╛рд░реНрди рдорджреНрджрдд рдЧрд░реНрдиреБрд╣реЛрд╕реН

рдорд▓рд╛рдИ рд▓рд╛рдЧреНрдЫ рдХрд┐ рд╡рд┐рдХрд╛рд╕рдХрд░реНрддрд╛рд╣рд░реВ рдкрд╣рд┐рд▓реЗ рдпрд╕ рд▓реЗрдЦрдорд╛ рд░реБрдЪрд┐ рд░рд╛рдЦреНрдЫрдиреНред рддрдкрд╛рдИрд▓реЗ рдЖрдлреНрдиреЛ рдорд╛рд▓рд┐рдХрд▓рд╛рдИ рд╕реЗрдиреНрдЯреНрд░реАрд▓рд╛рдИ рдПрдХреАрдХреГрдд рдЧрд░реНрди рдордирд╛рдЙрди рдХрд╛рд░рдгрд╣рд░реВрдХреЛ рдпреЛ рд╕реВрдЪреА рдкрдирд┐ рдкреНрд░рдпреЛрдЧ рдЧрд░реНрди рд╕рдХреНрдиреБрд╣реБрдиреНрдЫред

рд╡реНрдпрд╛рдкрд╛рд░ рд╕реВрдЪреАрдорд╛ рдЕрдиреНрддрд┐рдо рд╡рд╕реНрддреБрд╕рдБрдЧ рд╕рд╛рд╡рдзрд╛рди рд░рд╣рдиреБрд╣реЛрд╕реНред

рддрдкрд╛рдИрдВ рдкрд╣рд┐рд▓реЗ рдиреИ рд░реБрдЪрд┐ рдЫ?

рд╕реЗрдиреНрдЯреНрд░реА рдкреНрд░рдпреЛрдЧ рдЧрд░реЗрд░ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдЕрдиреБрдкреНрд░рдпреЛрдЧрдорд╛ рдЯреНрд░реНрдпрд╛рдХрд┐рдЩ рддреНрд░реБрдЯрд┐рд╣рд░реВ

рд╕реЗрдиреНрдЯреНрд░реА рднрдиреЗрдХреЛ рдХреЗ рд╣реЛ?

рд╕реЗрдиреНрдЯреНрд░реА рдПрдХ рдЦреБрд▓рд╛ рд╕реНрд░реЛрдд рдмрдЧ рдЯреНрд░реНрдпрд╛рдХрд┐рдЩ рдЕрдиреБрдкреНрд░рдпреЛрдЧ рд╣реЛ рдЬрд╕рд▓реЗ рд╡рд┐рдХрд╛рд╕рдХрд░реНрддрд╛рд╣рд░реВрд▓рд╛рдИ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рд╕рдордпрдорд╛ рдХреНрд░реНрдпрд╛рд╕рд╣рд░реВ рдЯреНрд░реНрдпрд╛рдХ рдЧрд░реНрди рд░ рд╕рдорд╛рдзрд╛рди рдЧрд░реНрди рдорджреНрджрдд рдЧрд░реНрджрдЫред рдирдмрд┐рд░реНрд╕рдиреБрд╣реЛрд╕реН рдХрд┐ рдЕрдиреБрдкреНрд░рдпреЛрдЧрд▓реЗ рддрдкрд╛рдИрдВрд▓рд╛рдИ рджрдХреНрд╖рддрд╛ рдмрдврд╛рдЙрди рд░ рдкреНрд░рдпреЛрдЧрдХрд░реНрддрд╛ рдЕрдиреБрднрд╡ рд╕реБрдзрд╛рд░ рдЧрд░реНрди рдЕрдиреБрдорддрд┐ рджрд┐рдиреНрдЫред рд╕реЗрдиреНрдЯреНрд░реАрд▓реЗ рдЬрд╛рднрд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ, рдиреЛрдб, рдкрд╛рдЗрдерди, PHP, рд░реБрдмреА, рдЬрд╛рднрд╛ рд░ рдЕрдиреНрдп рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдЩ рднрд╛рд╖рд╛рд╣рд░реВ рд╕рдорд░реНрдерди рдЧрд░реНрджрдЫред

рд╕реЗрдиреНрдЯреНрд░реА рдкреНрд░рдпреЛрдЧ рдЧрд░реЗрд░ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдЕрдиреБрдкреНрд░рдпреЛрдЧрдорд╛ рдЯреНрд░реНрдпрд╛рдХрд┐рдЩ рддреНрд░реБрдЯрд┐рд╣рд░реВ

2. рд▓рдЧрдЗрди рдЧрд░реНрдиреБрд╣реЛрд╕реН рд░ рдПрдЙрдЯрд╛ рдкрд░рд┐рдпреЛрдЬрдирд╛ рд╕рд┐рд░реНрдЬрдирд╛ рдЧрд░реНрдиреБрд╣реЛрд╕реН

  • рдЖрдлреНрдиреЛ рд╕реЗрдиреНрдЯреНрд░реА рдЦрд╛рддрд╛ рдЦреЛрд▓реНрдиреБрд╣реЛрд╕реНред рддрдкрд╛рдИрдВрд▓реЗ рд▓рдЧ рдЗрди рдЧрд░реНрдиреБрдкрд░реНрдиреЗ рд╣реБрди рд╕рдХреНрдЫред (рдХреГрдкрдпрд╛ рдзреНрдпрд╛рди рджрд┐рдиреБрд╣реЛрд╕реН рдХрд┐ рд╕реЗрдиреНрдЯреНрд░реА рддрдкрд╛рдИрдХреЛ рд╕рд░реНрднрд░рдорд╛ рд╕реНрдерд╛рдкрдирд╛ рдЧрд░реНрди рд╕рдХрд┐рдиреНрдЫ)
  • рдЕрд░реНрдХреЛ рдЪрд░рдг рдПрдХ рдкрд░рд┐рдпреЛрдЬрдирд╛ рд╕рд┐рд░реНрдЬрдирд╛ рдЧрд░реНрди рдЫ
  • рд╕реВрдЪреАрдмрд╛рдЯ рдЖрдлреНрдиреЛ рднрд╛рд╖рд╛ рдЪрдпрди рдЧрд░реНрдиреБрд╣реЛрд╕реНред (рд╣рд╛рдореА рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдЪрдпрди рдЧрд░реНрди рдЬрд╛рдБрджреИрдЫреМрдВред "рдкреНрд░реЛрдЬреЗрдХреНрдЯ рд╕рд┐рд░реНрдЬрдирд╛ рдЧрд░реНрдиреБрд╣реЛрд╕реН" рдорд╛ рдХреНрд▓рд┐рдХ рдЧрд░реНрдиреБрд╣реЛрд╕реН)

рд╕реЗрдиреНрдЯреНрд░реА рдкреНрд░рдпреЛрдЧ рдЧрд░реЗрд░ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдЕрдиреБрдкреНрд░рдпреЛрдЧрдорд╛ рдЯреНрд░реНрдпрд╛рдХрд┐рдЩ рддреНрд░реБрдЯрд┐рд╣рд░реВ

рдЖрдлреНрдиреЛ рдЖрд╡реЗрджрди рдЕрдиреБрдХреВрд▓рди рдЧрд░реНрдиреБрд╣реЛрд╕реНред рд╕реЗрдиреНрдЯреНрд░реАрд▓рд╛рдИ рдХрдиреНрдЯреЗрдирд░рдорд╛ рдХрд╕рд░реА рдПрдХреАрдХреГрдд рдЧрд░реНрдиреЗ рднрдиреНрдиреЗ рдЖрдзрд╛рд░рднреВрдд рдЙрджрд╛рд╣рд░рдг рддрд▓ рд╣реЗрд░реНрди рд╕рдХрд┐рдиреНрдЫ:

import * as Sentry from '@sentry/browser';
// Sentry.init({
//  dsn: "<https://[email protected]/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;
        }
    }
}

рд╕реЗрдиреНрдЯреНрд░реАрд╕рдБрдЧ рддрдкрд╛рдИрд▓рд╛рдИ рдЕрд░реНрдХреЛ рдХреЗ рдЧрд░реНрдиреБ рдкрд░реНрдЫ рднрдиреЗрд░ рдкрддреНрддрд╛ рд▓рдЧрд╛рдЙрди рдорджреНрджрдд рдЧрд░реНрдирдХреЛ рд▓рд╛рдЧрд┐ рдЙрдкрдпреЛрдЧреА рд╡рд┐рдЬрд╛рд░реНрдб рдЫред рддрдкрд╛рдИрдВ рдпреА рдЪрд░рдгрд╣рд░реВ рдкрд╛рд▓рдирд╛ рдЧрд░реНрди рд╕рдХреНрдиреБрд╣реБрдиреНрдЫред рдо рддрдкрд╛рдЗрдБрд▓рд╛рдИ рддрдкрд╛рдЗрдБрдХреЛ рдкрд╣рд┐рд▓реЛ рддреНрд░реБрдЯрд┐ рд╣реНрдпрд╛рдиреНрдбрд▓рд░ рдХрд╕рд░реА рд╕рд┐рд░реНрдЬрдирд╛ рдЧрд░реНрдиреЗ рднрдиреЗрд░ рджреЗрдЦрд╛рдЙрди рдЪрд╛рд╣рдиреНрдЫреБред рд░рд╛рдореНрд░реЛ, рд╣рд╛рдореАрд▓реЗ рдПрдЙрдЯрд╛ рдкрд░рд┐рдпреЛрдЬрдирд╛ рд╕рд┐рд░реНрдЬрдирд╛ рдЧрд░реЗрдХрд╛ рдЫреМрдВ! рдЕрд░реНрдХреЛ рдЪрд░рдгрдорд╛ рдЬрд╛рдФрдВ

3. рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рд░ рд╕реЗрдиреНрдЯреНрд░реА рдПрдХреАрдХрд░рдг

рддрдкрд╛рдИрдВрд▓реЗ рдЖрдлреНрдиреЛ рдкрд░рд┐рдпреЛрдЬрдирд╛рдорд╛ тАЛтАЛnpm рдкреНрдпрд╛рдХреЗрдЬ рд╕реНрдерд╛рдкрдирд╛ рдЧрд░реНрдиреБрдкрд░реНрдЫред

npm i @sentry/browser

рддрдкрд╛рдИрдВрдХреЛ рдХрдиреНрдЯреЗрдирд░рдорд╛ рд╕реЗрдиреНрдЯреНрд░реА рд╕реБрд░реБ рдЧрд░реНрдиреБрд╣реЛрд╕реН:

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

DSN рдкрд░рд┐рдпреЛрдЬрдирд╛рд╣рд░реВ -> рд╕реЗрдЯрд┐рдЩрд╣рд░реВ -> рдЧреНрд░рд╛рд╣рдХ рдХреБрдЮреНрдЬреАрд╣рд░реВрдорд╛ рдЕрд╡рд╕реНрдерд┐рдд рдЫред рддрдкрд╛рдИрд▓реЗ рдЦреЛрдЬ рдкрдЯреНрдЯреАрдорд╛ рдЧреНрд░рд╛рд╣рдХ рдХреБрдЮреНрдЬреАрд╣рд░реВ рдлреЗрд▓рд╛ рдкрд╛рд░реНрди рд╕рдХреНрдиреБрд╣реБрдиреНрдЫред

рд╕реЗрдиреНрдЯреНрд░реА рдкреНрд░рдпреЛрдЧ рдЧрд░реЗрд░ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдЕрдиреБрдкреНрд░рдпреЛрдЧрдорд╛ рдЯреНрд░реНрдпрд╛рдХрд┐рдЩ рддреНрд░реБрдЯрд┐рд╣рд░реВ

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

4. рдкрд╣рд┐рд▓реЛ рддреНрд░реБрдЯрд┐ рдЯреНрд░реНрдпрд╛рдХ рдЧрд░реНрджреИ

рдЙрджрд╛рд╣рд░рдг рдХреЛ рд▓рд╛рдЧреА, рдореИрд▓реЗ Deezer API рдХреЛ рд╕рд╛рде рдПрдХ рд╕рд╛рдзрд╛рд░рдг рд╕рдВрдЧреАрдд рдЕрдиреБрдкреНрд░рдпреЛрдЧ рдкреНрд░рдпреЛрдЧ рдЧрд░реЗрдВред рддрдкрд╛рдИрдВ рдпрд╕рд▓рд╛рдИ рджреЗрдЦреНрди рд╕рдХреНрдиреБрд╣реБрдиреНрдЫ рдпрд╣рд╛рдБред рд╣рд╛рдореАрд▓реЗ рддреНрд░реБрдЯрд┐ рд╕рд┐рд░реНрдЬрдирд╛ рдЧрд░реНрди рдЖрд╡рд╢реНрдпрдХ рдЫред рдПрдЙрдЯрд╛ рддрд░рд┐рдХрд╛ "рдЕрдкрд░рд┐рднрд╛рд╖рд┐рдд" рд╕рдореНрдкрддреНрддрд┐ рдкрд╣реБрдБрдЪ рдЧрд░реНрди рд╣реЛ

рд╣рд╛рдореАрд▓реЗ рдХрд▓ рдЧрд░реНрдиреЗ рдмрдЯрди рд╕рд┐рд░реНрдЬрдирд╛ рдЧрд░реНрди рдЖрд╡рд╢реНрдпрдХ рдЫ console.log ╤Б user.emailред рдпреЛ рдХрд╛рд░реНрдп рдкрдЫрд┐ рд╣рд╛рдореАрд▓реЗ рддреНрд░реБрдЯрд┐ рд╕рдиреНрджреЗрд╢ рдкреНрд░рд╛рдкреНрдд рдЧрд░реНрдиреБрдкрд░реНрдЫ: рдирдкрдврд┐рдПрдХреЛ 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://[email protected]/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);

рдпреЛ рдмрдЯрди рдПрдХреАрдХреГрдд рдЧрд░реЗрдкрдЫрд┐, рддрдкрд╛рдИрдВрд▓реЗ рдмреНрд░рд╛рдЙрдЬрд░рдорд╛ рдкрд░реАрдХреНрд╖рдг рдЧрд░реНрдиреБрдкрд░реНрдЫред

рд╕реЗрдиреНрдЯреНрд░реА рдкреНрд░рдпреЛрдЧ рдЧрд░реЗрд░ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдЕрдиреБрдкреНрд░рдпреЛрдЧрдорд╛ рдЯреНрд░реНрдпрд╛рдХрд┐рдЩ рддреНрд░реБрдЯрд┐рд╣рд░реВ

рд╣рд╛рдореНрд░реЛ рдкрд╣рд┐рд▓реЛ рдЧрд▓реНрддреА рдЫ

рд╕реЗрдиреНрдЯреНрд░реА рдкреНрд░рдпреЛрдЧ рдЧрд░реЗрд░ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдЕрдиреБрдкреНрд░рдпреЛрдЧрдорд╛ рдЯреНрд░реНрдпрд╛рдХрд┐рдЩ рддреНрд░реБрдЯрд┐рд╣рд░реВ

рдУрд╣реЛ!

рд╕реЗрдиреНрдЯреНрд░реА рдкреНрд░рдпреЛрдЧ рдЧрд░реЗрд░ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдЕрдиреБрдкреНрд░рдпреЛрдЧрдорд╛ рдЯреНрд░реНрдпрд╛рдХрд┐рдЩ рддреНрд░реБрдЯрд┐рд╣рд░реВ

рдпрджрд┐ рддрдкрд╛рдИрдВрд▓реЗ рд╣реЗрдбрд░ рддреНрд░реБрдЯрд┐рдорд╛ рдХреНрд▓рд┐рдХ рдЧрд░реНрдиреБрднрдпреЛ рднрдиреЗ, рддрдкрд╛рдИрдВрд▓реЗ рд╕реНрдЯреНрдпрд╛рдХ рдЯреНрд░реЗрд╕ рджреЗрдЦреНрдиреБрд╣реБрдиреЗрдЫред

рд╕реЗрдиреНрдЯреНрд░реА рдкреНрд░рдпреЛрдЧ рдЧрд░реЗрд░ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдЕрдиреБрдкреНрд░рдпреЛрдЧрдорд╛ рдЯреНрд░реНрдпрд╛рдХрд┐рдЩ рддреНрд░реБрдЯрд┐рд╣рд░реВ

рд╕рдиреНрджреЗрд╢рд╣рд░реВ рдирд░рд╛рдореНрд░реЛ рджреЗрдЦрд┐рдиреНрдЫрдиреНред рдирд┐рд╕реНрд╕рдиреНрджреЗрд╣ рд╣рд╛рдореАрд▓реЗ рдХреЛрдб рдХрд╣рд╛рдБ рдЫ рднрдиреЗрд░ рдирдмреБрдЭреЗрд░ рддреНрд░реБрдЯрд┐ рд╕рдиреНрджреЗрд╢рд╣рд░реВ рджреЗрдЦреЗрдХрд╛ рдЫреМрдВред рдкреВрд░реНрд╡рдирд┐рд░реНрдзрд╛рд░рд┐рдд рд░реВрдкрдорд╛ рд╣рд╛рдореА ReactJS рдорд╛ рд╕реНрд░реЛрдд рдирдХреНрд╕рд╛рдХреЛ рдмрд╛рд░реЗрдорд╛ рдХреБрд░рд╛ рдЧрд░реНрджреИрдЫреМрдВ рдХрд┐рдирднрдиреЗ рддрд┐рдиреАрд╣рд░реВ рдХрдиреНрдлрд┐рдЧрд░ рдЧрд░рд┐рдПрдХрд╛ рдЫреИрдирдиреНред

рдо рд╕реНрд░реЛрдд рдирдХреНрд╕рд╛ рд╕реЗрдЯрдЕрдк рдЧрд░реНрди рдирд┐рд░реНрджреЗрд╢рдирд╣рд░реВ рдкрдирд┐ рдкреНрд░рджрд╛рди рдЧрд░реНрди рдЪрд╛рд╣рдиреНрдЫреБ, рддрд░ рдпрд╕рд▓реЗ рдпреЛ рд▓реЗрдЦрд▓рд╛рдИ рдореИрд▓реЗ рдЪрд╛рд╣реЗрдХреЛ рднрдиреНрджрд╛ рдзреЗрд░реИ рд▓рд╛рдореЛ рдмрдирд╛рдЙрдиреЗрдЫред

рддрдкрд╛рдИрдВ рдпреЛ рд╡рд┐рд╖рдп рдЕрдзреНрдпрдпрди рдЧрд░реНрди рд╕рдХреНрдиреБрд╣реБрдиреНрдЫ рдпрд╣рд╛рдБред рдпрджрд┐ рддрдкрд╛рдЗрдБ рдпрд╕ рд▓реЗрдЦрдорд╛ рд░реБрдЪрд┐ рд░рд╛рдЦреНрдиреБрд╣реБрдиреНрдЫ рднрдиреЗ, рджрд┐рдорд┐рддреНрд░реА рдиреЛрдЬреЗрдиреНрдХреЛ рд╕реНрд░реЛрдд рдирдХреНрд╕рд╛ рдПрдХреАрдХрд░рдгрдХреЛ рдмрд╛рд░реЗрдорд╛ рджреЛрд╕реНрд░реЛ рднрд╛рдЧ рдкреНрд░рдХрд╛рд╢рд┐рдд рдЧрд░реНрдиреЗрдЫред рддреНрдпрд╕реЛрднрдП, рдзреЗрд░реИ рд▓рд╛рдЗрдХ рд╣рд┐рдЯ рдЧрд░реНрдиреБрд╣реЛрд╕реН рд░ рд╕рджрд╕реНрдпрддрд╛ рд▓рд┐рдиреБрд╣реЛрд╕реН рджрд┐рдорд┐рддреНрд░реА рдиреЛрдЬреЗрдиреНрдХреЛрджреЛрд╕реНрд░реЛ рднрд╛рдЧ рдирдЫреБрдЯрд╛рдЙрдирдХреЛ рд▓рд╛рдЧрд┐ред

реи. рдЙрдкрдпреЛрдЧ Sentry рдЕрдиреНрдд рдмрд┐рдиреНрджреБ рд╕рдВрдЧ рдПрдкреАрдЖрдИ

рдард┐рдХ рдЫред рд╣рд╛рдореАрд▓реЗ рдЕрдШрд┐рд▓реНрд▓реЛ рдЕрдиреБрдЪреНрдЫреЗрджрд╣рд░реВрдорд╛ рдЬрд╛рднрд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдЕрдкрд╡рд╛рджрд▓рд╛рдИ рдХрднрд░ рдЧрд░реЗрдХрд╛ рдЫреМрдВред рдпрджреНрдпрдкрд┐, рд╣рд╛рдореА XHR рддреНрд░реБрдЯрд┐рд╣рд░реВрдХреЛ рдмрд╛рд░реЗрдорд╛ рдХреЗ рдЧрд░реНрдиреЗрдЫреМрдВ?

рд╕реЗрдиреНрдЯреНрд░реАрд╕рдБрдЧ рдЕрдиреБрдХреВрд▓рди рддреНрд░реБрдЯрд┐ рд╣реНрдпрд╛рдиреНрдбрд▓рд┐рдВрдЧ рдкрдирд┐ рдЫред рдореИрд▓реЗ рдпрд╕рд▓рд╛рдИ рдПрдкреАрдЖрдИ рддреНрд░реБрдЯрд┐рд╣рд░реВ рдЯреНрд░реНрдпрд╛рдХ рдЧрд░реНрди рдкреНрд░рдпреЛрдЧ рдЧрд░реЗрдВред

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": "[email protected]"})
          .setLevel("Error")
      );
      return Sentry.captureException(err);
    }

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

рдо рдХреНрдпрд╛рдЪ API рдХреЛ рд▓рд╛рдЧреА рд╕рд╛рдорд╛рдиреНрдп рдкреНрд░рдХрд╛рд░реНрдп рдкреНрд░рдпреЛрдЧ рдЧрд░реНрди рдЪрд╛рд╣рдиреНрдЫреБред

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

рддрдкрд╛рдИрдВрдХреЛ рдПрдкреАрдЖрдИ рдХрд▓рдорд╛ рдпреЛ рдкреНрд░рдХрд╛рд░реНрдп рдЖрдпрд╛рдд рдЧрд░реНрдиреБрд╣реЛрд╕реНред

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

рд╡рд┐рдзрд┐рд╣рд░реВ рдЬрд╛рдБрдЪ рдЧрд░реМрдВ:

  • рд╕реЗрдЯ рд╕реНрддрд░ рддрдкрд╛рдИрдВрд▓рд╛рдИ рд╕реЗрдиреНрдЯреНрд░реА рдбреНрдпрд╛рд╕рдмреЛрд░реНрдбрдорд╛ рд╕реНрддрд░ рддреНрд░реБрдЯрд┐ рд╕рдореНрдорд┐рд▓рд┐рдд рдЧрд░реНрди рдЕрдиреБрдорддрд┐ рджрд┐рдиреНрдЫред рдпрд╕рдорд╛ рдЧреБрдгрд╣рд░реВ рдЫрдиреН - 'рдШрд╛рддрдХ', 'рддреНрд░реБрдЯрд┐', 'рдЪреЗрддрд╛рд╡рдиреА', 'рд▓рдЧ', 'рдЬрд╛рдирдХрд╛рд░реА, 'рдбрд┐рдмрдЧ', 'рдХреНрд░рд┐рдЯрд┐рдХрд▓')ред
  • рд╕реЗрдЯ рдкреНрд░рдпреЛрдЧрдХрд░реНрддрд╛ рдХреБрдиреИ рдкрдирд┐ рдкреНрд░рдпреЛрдЧрдХрд░реНрддрд╛ рдбреЗрдЯрд╛ (рдЖрдИрдбреА, рдЗрдореЗрд▓ рдареЗрдЧрд╛рдирд╛, рднреБрдХреНрддрд╛рдиреА рдпреЛрдЬрдирд╛, рдЖрджрд┐) рдмрдЪрдд рдЧрд░реНрди рдорджреНрджрдд рдЧрд░реНрджрдЫред
  • рд╕реЗрдЯ рдЕрддрд┐рд░рд┐рдХреНрдд рддрдкрд╛рдИрдВрд▓рд╛рдИ рдЖрд╡рд╢реНрдпрдХ рдкрд░реНрдиреЗ рдХреБрдиреИ рдкрдирд┐ рдбрд╛рдЯрд╛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдЧрд░реНрди рдЕрдиреБрдорддрд┐ рджрд┐рдиреНрдЫ, рдЙрджрд╛рд╣рд░рдгрдХрд╛ рд▓рд╛рдЧрд┐, рднрдгреНрдбрд╛рд░ред

рдпрджрд┐ рддрдкрд╛рдЗрдБ рдмрдЧ рдмрд╛рд░реЗ рдкреНрд░рдпреЛрдЧрдХрд░реНрддрд╛ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдкреНрд░рд╛рдкреНрдд рдЧрд░реНрди рдЪрд╛рд╣рдиреБрд╣реБрдиреНрдЫ рднрдиреЗ, рддрдкрд╛рдЗрдБ showReportDialog рдкреНрд░рдХрд╛рд░реНрдп рдкреНрд░рдпреЛрдЧ рдЧрд░реНрдиреБрдкрд░реНрдЫред

Sentry.showReportDialog();

рдирд┐рд╖реНрдХрд░реНрд╖:

рдЖрдЬ рд╣рд╛рдореАрд▓реЗ рд╕реЗрдиреНрдЯреНрд░реАрд▓рд╛рдИ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдЕрдиреБрдкреНрд░рдпреЛрдЧрдорд╛ рдПрдХреАрдХреГрдд рдЧрд░реНрдиреЗ рдПрдЙрдЯрд╛ рддрд░рд┐рдХрд╛ рд╡рд░реНрдгрди рдЧрд░реНтАНрдпреМрдВред

тЖТ рдЯреЗрд▓рд┐рдЧреНрд░рд╛рдо рдЪреНрдпрд╛рдЯ рджреНрд╡рд╛рд░рд╛ Sentry

рд╕реНрд░реЛрдд: www.habr.com

рдПрдХ рдЯрд┐рдкреНрдкрдгреА рдердкреНрди