แฉแแแ แแแแแแแแ Sentry-แก แแแแแงแแแแแแก React-แแแ แแ แแแ.
แแก แกแขแแขแแ แแ แแก แกแแ แแแก แแแฌแแแ, แ แแแแแแช แแฌแงแแแ Sentry แจแแชแแแแแแแก แแแฎแกแแแแแแ แแแแแแแแแก แแแแแงแแแแแแ:
React-แแก แแแแแแแแแขแแชแแ
แฏแแ แฃแแแ แแแแแแแขแแ แแฎแแแ Sentry แแ แแแฅแขแ แแ แแแแแแแชแแแกแแแแก; Sentry แแแแกแแแขแแแแ. แแ แจแแแแฎแแแแแจแ แแแ แฉแแแ React.
แฉแแแ แฎแแแแฎแแ แแแแแแฎแแ แชแแแแแแ แฉแแแแก แแ แฆแแแแแก, Hello แแ Error, React-แแก แแแแแแแชแแแจแ. แฉแแแ แแแฌแงแแแ แฉแแแแ แแแแฌแงแแแ แแแแแแแชแแแก แจแแฅแแแแ:
npx create-react-app react-app
แจแแแแแ แฉแแแ แจแแแแแแขแแแแ Sentry แแแแแขแ:
yarn add @sentry/browser
แแ แแแแชแแแแแแแชแแ:
react-app/src/index.js
...
import * as Sentry from '@sentry/browser';
const RELEASE = '0.1.0';
if (process.env.NODE_ENV === 'production') {
Sentry.init({
dsn: 'https://[email protected]/1289887',
release: RELEASE,
});
}
...
แแแแแแ แแแแ:
- แแแแแแแแ แแแแก แแ แแก, แฉแแแ แแแแฅแแก แกแฎแแ แแแฅแแแแแแแแ แแแแแขแแ แแแแแก แกแแแแแฎแแแแกแแแแก, แ แแแแ แแชแแ แแแแกแแแ, แแแแขแแ แฉแแแ แแฃแจแแแแ แแฎแแแแ Sentry-แก แกแแฌแแ แแแ แแแแกแขแ แฃแฅแชแแแแแกแแแแก
แจแแแแแ แฉแแแ แแแฎแแ แชแแแแแแ Hello แแ Error แฆแแแแแแแก แแ แแแแแขแแแ แแแ แแแแแแแชแแแจแ:
react-app/src/Hello.js
import React, { Component } from 'react';
import * as Sentry from '@sentry/browser';
export default class Hello extends Component {
state = {
text: '',
};
render() {
const { text } = this.state;
return (
<div>
<button
onClick={this.handleClick}
>
Hello
</button>
<div>{text}</div>
</div>
)
}
handleClick = () => {
this.setState({
text: 'Hello World',
});
try {
throw new Error('Caught');
} catch (err) {
if (process.env.NODE_ENV !== 'production') {
return;
}
Sentry.captureException(err);
}
}
}
react-app/src/MyError.js
import React, { Component } from 'react';
export default class MyError extends Component {
render() {
return (
<div>
<button
onClick={this.handleClick}
>
Error
</button>
</div>
)
}
handleClick = () => {
throw new Error('Uncaught');
}
}
react-app/src/App.js
...
import Hello from './Hello';
import MyError from './MyError';
class App extends Component {
render() {
return (
<div className="App">
...
<Hello />
<MyError />
</div>
);
}
}
export default App;
แแ แแแแแแ (Source Maps)
แฉแแแ แจแแแแแซแแแ แจแแแแแแฌแแแ Sentry แกแแฌแแ แแแ แแแแกแขแ แฃแฅแชแแแ แจแแงแแแแแ:
yarn build
แแ build แกแแฅแแฆแแแแแแแ แจแแแงแแแแแ:
npx http-server -c-1
แแ แแแแแแ, แ แแแแแกแแช แแแจแแแแ แฌแแแแฌแงแแแ, แแ แแก แแก, แ แแ Sentry-แแก แจแแชแแแแแก แฉแแแแฌแแ แแแ แแฎแแแ แฎแแแแแแก แแแแ แแแก แแแแแคแแชแแ แแแฃแแ แแแ แขแแแจแ; แแ แแ แแก แซแแแแแ แกแแกแแ แแแแแ.
Sentry แกแแ แแแกแ แแแแก แแแแแแ แขแแแก แจแแชแแแแแก แแแฆแแแแก แจแแแแแ แฌแงแแ แแก แ แฃแแแแแก แแแแฆแแแแ แจแแแชแแ แแแฃแแ แแแแแขแแกแแแแก. แแ แจแแแแฎแแแแแจแ แฉแแแ แแแฃแจแแแแ แแแแแแฐแแกแขแแแแ (แแ แแ แแก แฎแแแแแกแแฌแแแแแ Sentry แกแแ แแแกแแกแแแแก).
แแแแแฌแงแแแขแแแแแแแ (แฌแงแแ แแก แ แฃแแแแ)
แแ แแ แแแแแแแก แแแแแฌแงแแแขแ แแ แแก แแแแแแแชแแแก แแแจแแแแ แกแแฏแแ แ แแแ แกแแ แแแ แแแแ. แแ แแ แแแ แขแแแ แแแกแฃแฎแแก แฆแแแแแ GitHub Pages แกแแ แแแกแแก แแแแแกแแงแแแแแแแ (แฃแคแแกแ). แแแแแงแแแแแแก แแแแแฏแแแ, แ แแแแ แช แฌแแกแ, แจแแแแแแแ:
-
แแแแแแแแ แแ แกแแฅแแฆแแแแแก แจแแแแแ แกแ แแแแจแแแแ แกแแฅแแฆแแแแแจแ Docs แกแแชแแแแก แซแแ แแฃแ แแแ แแฅแขแแ แแแจแ.
-
แฉแแ แแแ GitHub แแแแ แแแแ แกแแชแแแจแ (GitHub-แแแ), แ แแแ แแแแแแงแแแแ docs แกแแฅแแฆแแแแ แกแแแแแแกแขแ แ แคแแแแแแแแ
-
แแแแงแแแแ แชแแแแแแแแแ GitHub-แจแ
แจแแแแจแแแ: แแแก แจแแแแแ แ แแช แแแแแ แแแแ, แ แแกแ แแแแแงแแแแแ แแญแแ แแแแ แจแแฅแแแ-แจแแฅแแแ-แแแ แกแแฌแงแแกแ แแแแ แแแก แคแฃแแฅแชแแ แแแแแแแชแแแก แแแกแแจแแแแแ. แแแแแแ แแแแแขแ.json-แจแ แจแแแแแแแก แแแแแขแแแแแแ:
"homepage": "https://larkintuckerllc.github.io/hello-sentry/"
แแแจแแแแฃแแ แแแแแแแชแแแก แกแแแแแแ แแแ แกแแ แฎแแแแแกแแฌแแแแแแ:
แแแญแแ แแแ แแแแแแแก แแแฃแกแขแ แแชแแ
แแแแแ แแแแแแ แแ Hello แฆแแแแแแ แแแฌแแแแฃแแแแแ.
แจแแชแแแแแ, แ แแแแแแช แแกแ แแแแแแงแฃแ แแแ:
แแแแแแ แแแแ:
- แแก แฎแแ แแแแแก แแแแแ แแจแ แแ แจแแแซแแแแ แแงแแก แฃแคแ แ แแแแคแแ, BRAVO.
แแแฃแแแแแแกแฌแแแแแแแ แจแแชแแแแแแแก แแแฃแกแขแ แแชแแ
แแแแแแแแฃแ แแ, แแแแแ แแแแแแ แแ แฆแแแแแแก แแแญแแ แแ แจแแชแแแแ.
แจแแชแแแแแ, แ แแแแแแช แแกแ แแแแแแงแฃแ แแแ:
แแแฃแแแแแแกแฌแแแแแแแ แจแแชแแแแแแแก แฃแแแ แแแแฃแจแแแแแ (แแแแแชแแแ)
แจแแชแแแแแแแก แแแแแขแแแแก แแแแแ แแแ
JavaScript-แแก แจแแชแแแแ แแแแฎแแแ แแแแแก แแแขแแ แคแแแกแแก แแแฌแแแจแ แแ แฃแแแ แแแแ แฆแแแแก แแแแแ แแแแแแแชแแ. React-แแก แแแแฎแแแ แแแแแแแกแแแแก แแ แแ แแแแแแแก แแแแแกแแญแ แแแแ, React 16 แฌแแ แแแแแแแแแ แแฎแแ แแแแชแแคแชแแแก แกแแฎแแแฌแแแแแแ "แจแแชแแแแแก แกแแแฆแแ แแแ".
แจแแชแแแแแก แกแแแฆแแ แแแ แแ แแก React แแแแแแแแแขแแแ, แ แแแแแแแช แแญแแ แแ JavaScript-แแก แจแแชแแแแแแก แกแแแแ แแแแ แจแแแแแแแแ แแแแแแแแแขแแก แฎแแจแ, แแฆแ แแชแฎแแแแ แแ แจแแชแแแแแแก แแ แแซแแแแแ แกแแ แแแแ แแ แแแขแแ แคแแแกแก แแ แแแแแแแแแขแแก แฎแแก แแแชแแแแ, แ แแแแแแช แฉแแแแแแ แแ. แจแแชแแแแแก แกแแแฆแแ แแแ แแญแแ แก แจแแชแแแแแแก แ แแแแแ แแก แแ แแก, แกแแกแแชแแชแฎแแ แชแแแแแก แแแแแแแแจแ แแ แแแ แฅแแแแแ แแแแแ แฎแแก แแแแกแขแ แฃแฅแขแแ แแแจแ.
...
แแฎแแแ แฅแชแแแ แแแแแฃแชแแแแ แจแแชแแแแแแแกแแแแก
แแก แชแแแแแแแ แแแแจแแแแแแแแแแ. React 16-แแก แแแแแแแ แแแแแ, แจแแชแแแแแแ, แ แแแแแแแช แแ แแฅแแ แแแคแแฅแกแแ แแแฃแแ แ แแแแ แจแแชแแแแแก แกแแแฆแแ แแแแ, แแแแแแฌแแแแก แแแแแ React แแแแแแแแแขแแก แฎแแก แแแแแแขแแแก.
- แแแ แแแ แแแแแ -
แจแแชแแแแแก แแแแฃแจแแแแแ React 16-แจแ
แแแแจแแแแแแแแแ แแแแแแ แขแแแ, แ แแแแแแช แชแแขแ แฎแแแ แแแแญแแ แแ, แกแแแแ แแแแก แแแแฎแแแแแแแ, แแ แแก แแก ะฒััะตัะฟะพะผัะฝััะพะต ะฟะพะฒะตะดะตะฝะธะต ัะฐะฑะพัะฐะตั ัะพะปัะบะพ ั ะพัะธะฑะบะฐะผะธ, ะณะตะฝะตัะธััะตะผัะผะธ ะฒ ะผะตัะพะดะต ัะตะฝะดะตัะธะฝะณะฐ (ะธะปะธ, ััะพ ะฑะพะปะตะต ะฒะตัะพััะฝะพ, ะฒ ะปัะฑะพะผ ะธะท ะผะตัะพะดะพะฒ ะถะธะทะฝะตะฝะฝะพะณะพ ัะธะบะปะฐ). แแแแแแแแแ, แจแแชแแแแแก แกแแแฆแแ แแแแก แแแแแงแแแแแ แแ แแแแแ แแแ แแก แแ แแแแขแแแก แฉแแแแก แฆแแแแแแ แจแแชแแแแ; แแก แจแแชแแแแ แแงแ แแแฌแแแแฃแแแแแก แแแแแฃแจแแแแแแแจแ.
แแแแแ แจแแแฅแแแแ แจแแชแแแแแก แแแแแชแแแแก แแแแแแแแ แแ แจแแแแแ แแแแแแแงแแแแ แจแแชแแแแแก แกแแแฆแแ แแแ, แ แแแ แจแแชแแแแแก แฃแคแ แ แแแฎแแแแแแแ แแแแฃแจแแแแแ แแแฎแแแก.
react-app/src/MyRenderError
import React, { Component } from 'react';
export default class MyRenderError extends Component {
state = {
flag: false,
};
render() {
const { flag } = this.state;
return (
<div>
<button
onClick={this.handleClick}
>
Render Error
</button>
{ flag && <div>{flag.busted.bogus}</div> }
</div>
)
}
handleClick = () => {
this.setState({
flag: true,
});
}
}
แแแแแแ แแแแ:
-
แ แแแแกแแช แแแแญแแ แแ แฆแแแแแก, แ แแแแแ แแแแก แแแฉแแแแแแ แแฅแแแแ แแ แแจแ.แแแขแแฎแแแ.แงแแแแ, แ แแแแแแช แฌแแ แแแฅแแแแก แจแแชแแแแแก
-
แจแแชแแแแแก แกแแแฆแแ แแก แแแ แแจแ, แแแแแ แแแแแแแแแขแแก แฎแ แแแแแแขแแแแแแ
แจแแแแแ แฉแแแ แแฌแแ แ แจแแชแแแแแก แกแแแฆแแ แแก แแแแก (แแงแแแแแก แกแแชแแชแฎแแแก แชแแแแแก แแฎแแ แแแแแแก แแแแแแแแแขแDidCatch); แแก แแ แกแแแแแแ แแ แแก แแแแแแแแ, แ แแแแแแช แแแชแแแฃแแแ แแแ แแแ แแแแแแก แกแขแแขแแแจแ:
react-app/src/ErrorBoundary.js
import React, { Component } from 'react';
import * as Sentry from '@sentry/browser';
export default class ErrorBoundary extends Component {
constructor(props) {
super(props);
this.state = { hasError: false };
}
componentDidCatch(err, info) {
this.setState({ hasError: true });
Sentry.captureException(err);
}
render() {
if (this.state.hasError) {
return <h1>Something went wrong.</h1>;
}
return this.props.children;
}
}
แกแแแแแแแ แแแงแแแแแ แแ แแแแแแแแแขแก:
react-app/src/App.js
...
import MyRenderError from './MyRenderError';
class App extends Component {
render() {
return (
<ErrorBoundary>
<div className="App">
...
</div>
</ErrorBoundary>
);
}
}
...
แแฃแแชแ, Render Error แฆแแแแแแ แแแฌแแแแฃแแแแแ แแแแแฉแแแแแ แกแแ แแแแ แแ แแแขแแ แคแแแกแ แแ แแชแแแแแแก แจแแชแแแแแก แจแแกแแฎแแ Sentry-แก.
แแแกแ แฃแแแแ
แแแแแ แแแฅแแก, แ แแ แแก แแฅแแแแแแแก แกแแกแแ แแแแแ แแฆแแแฉแแแ.
PS
PS Telegram แฉแแขแ Sentry-แแก แกแแจแฃแแแแแแ
แฌแงแแ แ: www.habr.com