Hari ini, saya akan memandu Anda melalui pelacakan kesalahan waktu nyata di aplikasi React. Aplikasi frontend biasanya tidak digunakan untuk pelacakan bug. Beberapa perusahaan sering menunda bug pelacakan dengan mengembalikannya setelah dokumentasi, tes, dan banyak lagi. Namun, jika Anda dapat mengubah produk Anda menjadi lebih baik, lakukan saja!
1. Mengapa Anda membutuhkan Sentry?
Saya berasumsi Anda tertarik untuk melacak bug selama produksi
Apakah menurut Anda ini tidak cukup?
Oke, mari kita lihat detailnya.
Alasan teratas menggunakan Sentry untuk pengembang:
- Menghilangkan risiko penerapan kode buggy
- Bantuan QA dalam pengujian kode
- Dapatkan pemberitahuan masalah dengan cepat
- Kemampuan untuk memperbaiki kesalahan dengan cepat
- Mendapatkan tampilan kesalahan yang nyaman di panel admin
- Kesalahan pengurutan berdasarkan segmen pengguna / browser
Alasan utama CEO / Pimpinan proyek
- Menghemat uang (Sentry dapat diinstal di server Anda)
- Mendapatkan umpan balik pengguna
- Pemahaman waktu nyata tentang apa yang salah dengan proyek Anda
- Memahami jumlah masalah yang dialami orang dengan aplikasi Anda
- Membantu menemukan tempat yang membuat kesalahan pengembang Anda
, . , 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.
, 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 , , , .
Jika Anda ingin mendapatkan umpan balik pengguna tentang bug, Anda harus menggunakan fungsi showReportDialog.
Sentry.showReportDialog();
Keluaran:
Hari ini kami menjelaskan satu cara untuk mengintegrasikan Sentry ke dalam aplikasi React.
→ Obrolan Telegram melalui Sentry