рд╕реЗрдВрдЯреНрд░реА рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд░рд┐рдПрдХреНрдЯ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдореЗрдВ рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЛ рдЯреНрд░реИрдХ рдХрд░рдирд╛

рд╕реЗрдВрдЯреНрд░реА рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд░рд┐рдПрдХреНрдЯ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдореЗрдВ рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЛ рдЯреНрд░реИрдХ рдХрд░рдирд╛

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

1. рдЖрдкрдХреЛ рд╕рдВрддрд░реА рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдХреНрдпреЛрдВ рд╣реИ?

рдореИрдВ рдорд╛рдирддрд╛ рд╣реВрдВ рдХрд┐ рдЖрдк рдЙрддреНрдкрд╛рджрди рдХреЗ рджреМрд░рд╛рди рдмрдЧреНрд╕ рдХреЛ рдЯреНрд░реИрдХ рдХрд░рдиреЗ рдореЗрдВ рд░реБрдЪрд┐ рд░рдЦрддреЗ рд╣реИрдВ

рдХреНрдпрд╛ рдЖрдкрдХреЛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдкрд░реНрдпрд╛рдкреНрдд рдирд╣реАрдВ рд╣реИ?

рдареАрдХ рд╣реИ, рдЖрдЗрдП рд╡рд┐рд╡рд░рдг рджреЗрдЦреЗрдВред

рдбреЗрд╡рд▓рдкрд░реНрд╕ рджреНрд╡рд╛рд░рд╛ рд╕реЗрдВрдЯреНрд░реА рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рдкреНрд░рдореБрдЦ рдХрд╛рд░рдг:

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

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

  • рдкреИрд╕реЗ рдмрдЪрд╛рдПрдВ (рд╕рдВрддрд░реА рдЖрдкрдХреЗ рд╕рд░реНрд╡рд░ рдкрд░ рд╕реНрдерд╛рдкрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ)
  • рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛
  • рд╡рд╛рд╕реНрддрд╡рд┐рдХ рд╕рдордп рдореЗрдВ рдпрд╣ рд╕рдордЭрдирд╛ рдХрд┐ рдЖрдкрдХреЗ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдореЗрдВ рдХреНрдпрд╛ рдЧрдбрд╝рдмрдбрд╝ рд╣реИ
  • рдЖрдкрдХреЗ рдРрдк рд╕реЗ рд▓реЛрдЧреЛрдВ рдХреЛ рд╣реЛрдиреЗ рд╡рд╛рд▓реА рд╕рдорд╕реНрдпрд╛рдУрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рдХреЛ рд╕рдордЭрдирд╛
  • рдЙрди рд╕реНрдерд╛рдиреЛрдВ рдХреЛ рдвреВрдВрдврдиреЗ рдореЗрдВ рдЖрдкрдХреА рд╕рд╣рд╛рдпрддрд╛ рдХрд░реЗрдВ рдЬрд╣рд╛рдВ рдЖрдкрдХреЗ рдбреЗрд╡рд▓рдкрд░реНрд╕ рдиреЗ рдЧрд▓рддрд┐рдпрд╛рдВ рдХреА рд╣реИрдВ

рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдбреЗрд╡рд▓рдкрд░реНрд╕ рдХреЛ рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ рдЗрд╕ рд▓реЗрдЦ рдореЗрдВ рджрд┐рд▓рдЪрд╕реНрдкреА рд╣реЛрдЧреАред рдЖрдк рдЕрдкрдиреЗ рдмреЙрд╕ рдХреЛ рд╕реЗрдВрдЯреНрд░реА рдХреЛ рдПрдХреАрдХреГрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдордирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд╛рд░рдгреЛрдВ рдХреА рдЗрд╕ рд╕реВрдЪреА рдХрд╛ рднреА рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

рд╡реНрдпрд╡рд╕рд╛рдп рд╕реВрдЪреА рдХреЗ рдЕрдВрддрд┐рдо рдЖрдЗрдЯрдо рд╕реЗ рд╕рд╛рд╡рдзрд╛рди рд░рд╣реЗрдВред

рдХреНрдпрд╛ рдЖрдк рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рд░реБрдЪрд┐ рд░рдЦрддреЗ рд╣реИрдВ?

рд╕реЗрдВрдЯреНрд░реА рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд░рд┐рдПрдХреНрдЯ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдореЗрдВ рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЛ рдЯреНрд░реИрдХ рдХрд░рдирд╛

рд╕рдВрддрд░реА рдХреНрдпрд╛ рд╣реИ?

рд╕реЗрдВрдЯреНрд░реА рдПрдХ рдУрдкрди рд╕реЛрд░реНрд╕ рдмрдЧ рдЯреНрд░реИрдХрд┐рдВрдЧ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рд╣реИ рдЬреЛ рдбреЗрд╡рд▓рдкрд░реНрд╕ рдХреЛ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рд╕рдордп рдореЗрдВ рдХреНрд░реИрд╢ рдХреЛ рдЯреНрд░реИрдХ рдХрд░рдиреЗ рдФрд░ рдареАрдХ рдХрд░рдиреЗ рдореЗрдВ рдорджрдж рдХрд░рддрд╛ рд╣реИред рдпрд╣ рди рднреВрд▓реЗрдВ рдХрд┐ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдЖрдкрдХреЛ рджрдХреНрд╖рддрд╛ рдмрдврд╝рд╛рдиреЗ рдФрд░ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдЕрдиреБрднрд╡ рдореЗрдВ рд╕реБрдзрд╛рд░ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред рд╕реЗрдВрдЯреНрд░реА рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ, рдиреЛрдб, рдкрд╛рдпрдерди, рдкреАрдПрдЪрдкреА, рд░реВрдмреА, рдЬрд╛рд╡рд╛ рдФрд░ рдЕрдиреНрдп рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рднрд╛рд╖рд╛рдУрдВ рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рддрд╛ рд╣реИред

рд╕реЗрдВрдЯреНрд░реА рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд░рд┐рдПрдХреНрдЯ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдореЗрдВ рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЛ рдЯреНрд░реИрдХ рдХрд░рдирд╛

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. рдкрд╣рд▓реА рддреНрд░реБрдЯрд┐ рдХреЛ рдЯреНрд░реИрдХ рдХрд░рдирд╛

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

рд╣рдореЗрдВ рдПрдХ рдмрдЯрди рдмрдирд╛рдирд╛ рд╣реЛрдЧрд╛ рдЬреЛ рдХреЙрд▓ рдХрд░реЗ рджрд┐рд▓рд╛рд╕рд╛ рджреЗрдирд╛ ╤Б рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛.рдИрдореЗрд▓. рдЗрд╕ рдХреНрд░рд┐рдпрд╛ рдХреЗ рдмрд╛рдж рд╣рдореЗрдВ рдПрдХ рддреНрд░реБрдЯрд┐ рд╕рдВрджреЗрд╢ рдкреНрд░рд╛рдкреНрдд рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП: рдзреНрдпрд╛рди рдореЗрдВ рди рдЖрдпрд╛ рд▓реЗрдЦрди рддреНрд░реБрдЯрд┐ (рдЕрдкрд░рд┐рднрд╛рд╖рд┐рдд рд╕реЗ рд╕рдВрдкрддреНрддрд┐ рдирд╣реАрдВ рдкрдврд╝ рд╕рдХрддрд╛ email) рдЙрдкрдпреЛрдХреНрддрд╛ рд╡рд╕реНрддреБ рдЧреБрдо рд╣реЛрдиреЗ рдХреЗ рдХрд╛рд░рдгред рдЖрдк рднреА рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдЕрдкрд╡рд╛рдж.

<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 рдореЗрдВ рд╕реНрд░реЛрдд рдорд╛рдирдЪрд┐рддреНрд░ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдд рдХрд░ рд░рд╣реЗ рд╣реИрдВ рдХреНрдпреЛрдВрдХрд┐ рд╡реЗ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдирд╣реАрдВ рд╣реИрдВред

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

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

5. рдЙрдкрдпреЛрдЧ рдкрд╣рд░реЗрджрд╛рд░ рдЕрдВрдд рдмрд┐рдВрджреБ рдХреЗ рд╕рд╛рде API

рдареАрдХ рд╣реИред рд╣рдордиреЗ рдкрд┐рдЫрд▓реЗ рдкреИрд░рд╛рдЧреНрд░рд╛рдл рдореЗрдВ рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдЕрдкрд╡рд╛рдж рдХреЛ рдХрд╡рд░ рдХрд┐рдпрд╛ рд╣реИред рд╣рд╛рд▓рд╛рдБрдХрд┐, рд╣рдо 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));
    }
  });

рдореИрдВ рдХреИрдЪ рдПрдкреАрдЖрдИ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рд╛рдорд╛рдиреНрдп рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдЪрд╛рд╣реВрдВрдЧрд╛ред

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

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

рдЖрдЬ рд╣рдордиреЗ рд╕реЗрдВрдЯреНрд░реА рдХреЛ рд░рд┐рдПрдХреНрдЯ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдореЗрдВ рдПрдХреАрдХреГрдд рдХрд░рдиреЗ рдХрд╛ рдПрдХ рддрд░реАрдХрд╛ рдмрддрд╛рдпрд╛ред

тЖТ рдЯреЗрд▓реАрдЧреНрд░рд╛рдо рдЪреИрдЯ рджреНрд╡рд╛рд░рд╛ рдкрд╣рд░реЗрджрд╛рд░

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

рдПрдХ рдЯрд┐рдкреНрдкрдгреА рдЬреЛрдбрд╝реЗрдВ