ืืืจ ืืืกืคืึธืจืฉื ื ืืฆื Sentry ืืื React.
ืืขืจ ืึทืจืืืงื ืืื ืืืื ืคืื ืึท ืกืขืจืืข ืกืืึทืจืืื ื ืืื ืจืืคึผืึธืจืืื ื ืกืขื ืืจื ืขืจืจืึธืจืก ื ืืฆื ืึท ืืืืฉืคึผืื:
ืืืคึผืืึทืืขื ืืืืฉืึทื ืคืื ืจืขืึทืงื
ืขืจืฉืืขืจ ืืืจ ืืึทืจืคึฟื ืฆื ืืืืื ืึท ื ืืึทืข ืกืขื ืืจื ืคึผืจืืืขืงื ืคึฟืึทืจ ืืขื ืึทืคึผืืึทืงืืืฉืึทื; ืคืื ืื Sentry ืืืขืืืืืื. ืืื ืืขื ืคืึทื, ืืืจ ืงืืืึทืื 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 ืคึฟืึทืจ ืคึผืจืึธืืืงืฆืืข ืืืืขื.
ืืขืจื ืึธื ืืืจ ืื ืกืืจืืืขื ื ืืื ืืืขืจ ืืขืื ืืื ืืขืืช ืงื ืขืคึผืืขื ืืื ืืืืื ืืื ืฆื ืื ืึทืคึผืืึทืงืืืฉืึทื:
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;
ืคึผืจืึธืืืขื (ืืงืืจ ืืึทืคึผืก)
ืืืจ ืงืขื ืขื ืคึผืจืืืืจื Sentry ืืื ืึท ืคึผืจืึธืืืงืฆืืข ืืืืขื ืืืจื ืึทืจืืึทื:
yarn build
ืืื ืคึฟืื ืื ืืืืขื ืืขืงืข ืึทืจืืึทื:
npx http-server -c-1
ืืขืจ ืคึผืจืึธืืืขื ืืืึธืก ืืืจ ืืื ืืืืคื ืืื ืืื ืึทื Sentry ืก ืืขืืช ืจืขืงืึธืจืืก ืึธืคึผืฉืืงื ืฆื ืฉืืจื ื ืืืขืจื ืืื ืื ืืื ืืคืืขื ืคึผืขืงื; ื ืื ืืืืขืจ ื ืืฆืืง.
ืื ืกืขื ืืจื ืกืขืจืืืืก ืืขืจืงืืขืจื ืืขื ืืืจื ืฆืืขื ืื ืืงืืจ ืืึทืคึผืก ืคึฟืึทืจ ืื ืจืืืืกื ืคึผืึทืงืึทื ื ืึธื ืืืงืืืขื ืึท ืืขืืช. ืืื ืืขื ืคืึทื, ืืืจ ืืืืคื ืคึฟืื ืืึธืงืึทืืืึธืกื (ื ืื ืฆืืืจืืืืขื ืืืจื ืื Sentry ืืื ืกื).
ืกืึทืืืฉืึทื ื (ืืงืืจ ืืึทืคึผืก)
ืื ืืืืืื ื ืฆื ืืขื ืคึผืจืึธืืืขื ืืื ืฆื ืืืืคื ืื ืึทืคึผืืึทืงืืืฉืึทื ืคึฟืื ืึท ืฆืืืืจ ืืืขื ืกืขืจืืืขืจ. ืืืื ืคึผืฉืื ืขื ืืคืขืจ ืงื ืขืคึผื ืฆื ื ืืฆื ืื GitHub ืืืขืืขืจ ืืื ืกื (ืคืจืื). ืื ืกืืขืคึผืก ืฆื ื ืืฆื ืืขื ืขื ืืืืฉืึทืืืึทืื ืืื ืืืื:
-
ื ืึธืืืึทืื ืื ืืื ืืึทืื ืคืื ืื ืืขืงืข ืืืืขื ืฆื ืืขืงืข ืืึธืงืก ืืื ืื ืืืึธืจืฆื ืืืขืืืืืึทืืขืจ ืคืื ืื ืจืืคึผืึทืืึทืืึธืจื.
-
ืฆืื ื ืื ืืืืืื ืืืขืืขืจ ืืื ืื ืจืืคึผืึทืืึทืืึธืจื (ืคึฟืื GitHub) ืฆื ื ืืฆื ืื ืืึธืงืก ืืขืงืข ืืื ืืึทืืขืืึธืก ืฆืืืืืื
-
ืคึผืืฉ ืขื ืืขืจืื ืืขื ืฆื GitHub
ืืึธื: ื ืึธื ืืื ืคืืืืขืจื ืืืืก ืืืึธืก ืืื ืืึทืจืคึฟื ืฆื ื ืืฆื ืฉืึทืคึฟื-ืฉืึทืคึฟื-ืึทืคึผ ืืืื ืืืึทื ืคืื ืงืฆืืข ืฆื ืงืึทืืขืจ ืื ืึทืคึผืืึทืงืืืฉืึทื. ืืขืงืืืขื ืฆื ืืืืื ืื ืคืืืืขื ืืข ืฆื package.json:
"homepage": "https://larkintuckerllc.github.io/hello-sentry/"
ืื ืืขืฆื ืืืขืจืกืืข ืคืื โโโโืื ืคืืืกื ืืืง ืึทืคึผืืึทืงืืืฉืึทื ืืื ืื ืืืฆื ืืื:
ืืืืืกืืจืืฆืืข ืคืื โโืงืึทื ืืึทืื
ืืื ืก ืืืื ืืืจื ืืขืื ืึท ืงืืืง ืืขื ืืขืื ืงื ืขืคึผื.
ืืื ืึท ืืขืืช ืืขืจืฉืืึทื ืขื ืืื ืืึธืก:
ืืืืขืจืงืื ืืขื:
- ืืขืจ ืืฉืืง ืืืจืืื ืงืขื ื ืืฉื ืืืื ืงืืืจืขืจ, ืืื ืืขืืื.
ืืืืืกืืจืึทืืืึธื ืคืื ืึทื ืึทืงืึทืื ืืขื ืคึฟืึทืจ ืขืจืจืึธืจืก
ืคึผืื ืงื ืึทืืื, ืืึธืื ืก ืืืื ืืืจื ืื ืงื ืขืคึผื ืืื ืืขืืช.
ืืื ืึท ืืขืืช ืืขืจืฉืืึทื ืขื ืืื ืืึธืก:
ืืขืกืขืจ ืืึทื ืืืื ื ืคืื ืึทื ืึทืงืึทืื ืืื ืขืจืจืึธืจืก (ืจืขื ืืขืจืื ื)
ืืงืืื ืคืื ืืขืืช ืืืืึทืฅ
ื ืืืฉืึทืืืึทืกืงืจืืคึผื ืืขืืช ืืื ืืืื ืคืื ืื ืืึทื ืืฆืขืจ ืฆืืืื ื ืืึธื ื ืืฉื ืืจืขืื ืื ืืื ืฆืข ืึทืคึผืืึทืงืืืฉืึทื. ืฆื ืกืึธืืืืข ืืขื ืคึผืจืึธืืืขื ืคึฟืึทืจ ืจืขืึทืงื ืืืืขืจื, React 16 ืื ืืจืึทืืืกืื ืึท ื ืืึทืข ืืึทืืจืืฃ ืืขืจืืคึฟื "ืืขืืช ืืืืื".
ืืขืืช ืืึทืื ืืจืื ืืขื ืขื ืจืขืึทืงื ืงืึทืืคึผืึธืื ืึทื ืฅ ืืืึธืก ืืึทืคึผื ืืืฉืึทืืืึทืกืงืจืืคึผื ืขืจืจืึธืจืก ืขืจืืขืฅ ืืื ืืืืขืจ ืงืื ื ืงืึธืืคึผืึธื ืขื ื ืืืื, ืงืืึธืฅ ืื ืขืจืจืึธืจืก ืืื ืืึทืื ืึท ืคืึทืืืึทืงืง ืื ืึทื ืฉืืึธื ืคืื ืื ืงืึธืืคึผืึธื ืขื ื ืืืื ืืืึธืก ืงืจืึทืฉื. ืืขืืช ืืึทืื ืืจืื ืืึทืคึผื ืขืจืจืึธืจืก ืืขืฉืึทืก ืจืขื ืืขืจืื ื, ืืื ืืืืคืกืืืงืึทื ืืขืืืึธืืก, ืืื ืืื ืื ืงืึทื ืกืืจืึทืงืืขืจื ืคืื ืื ืืื ืฆืข ืืืื ืืื ืืขืจ ืืื.
...
ื ืื ืึธืคึผืคืืจืื ื ืคึฟืึทืจ ืึทื ืืืืขืงืืื ืขืจืจืึธืจืก
ืืขื ืขื ืืขืจืื ื ืืื ืืึทืืืึทืืืง. ืืื ื ืจืขืึทืงื 16, ืขืจืจืึธืจืก ืืืึธืก ืืขื ืขื ื ืืฉื ืืขืืืคื ืืืจื ืงืืื ืืขืืช ืืจืขื ืขืฅ ืืืขื ืคืืจื ืฆื ืื ืืื ืฆืข ืจืขืึทืงื ืงืึธืืคึผืึธื ืขื ื ืืืื ืึทื ืืึธืื ืืขื.
- ืื ืืืจืืืืื โ
ืืขืืช ืืึทื ืืืื ื ืืื ืจืขืึทืงื 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,
});
}
}
ืืืืขืจืงืื ื:
-
ืืืขื ืืืจ ืืจืืงื ืืขื ืงื ืขืคึผื, React ืืืขื ืืืื ืืขืืืืื flag.busted.bogus, ืืืึธืก ืืืฉืขื ืขืจืืืฅ ืึท ืืขืืช
-
ืึธื ืึท ืืขืืช ืืจืขื ืขืฅ, ืื ืืื ืฆืข ืงืึธืืคึผืึธื ืขื ื ืืืื ืืืขื ืืืื ืึทื ืืึธืื ืืขื
ืืขืจื ืึธื ืืืจ ืฉืจืืึทืื ืืื ืืืขืจ ืืขืืช ืืจืขื ืขืฅ ืงืึธื (ื ืืฆื ืื ื ืืึทืข ืืืืคืกืืืงืึทื ืืืคึฟื componentDidCatch); ืืึธืก ืืื ืืืืกืืงืื ืืขืจ ืืืืฉืคึผืื ืืื ืื ืึทืืจืึทืืึธืื ืก ืึทืจืืืงื:
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>
);
}
}
...
ืึธืืขืจ, ืงืืืงืื ื ืืืืฃ ืื ืจืขื ืืขืจืขืจ ืืขืืช ืงื ืขืคึผื ืืืกืคึผืืืื ืื ืคืึทืืืึทืงืง ืื ืืื ืจืืคึผืึธืจืฅ ืึท ืืขืืช ืฆื Sentry.
ืงืึทืืคึผืืืฉืึทื
ืืื ืืึธืคึฟื ืืืจ ืืขืคึฟืื ืขื ืืขื ื ืืฆืืง.
ืคึผืก
ืคึผืก ืืขืืขืืจืึทื ืฉืืืขืกื ืืืจื ืกืขื ืืจื
ืืงืืจ: www.habr.com