Cara mencari bug di ujung depan: 4 tahap utama


Pada artikel ini saya akan mempertimbangkan masalah mengidentifikasi dan menangani kesalahan yang terjadi di frontend (browser atau tampilan web).

Di frontend, kode JS dieksekusi di browser. JavaScript bukan bahasa yang dikompilasi, jadi selalu ada kemungkinan kesalahan kinerja saat menggunakan program secara langsung. Kesalahan eksekusi memblokir kode yang terletak setelah tempat kesalahan, dan pengguna program berisiko mengambil sisanya dengan layar aplikasi non-fungsional yang hanya dapat dimuat ulang atau ditutup. Tetapi ada metode untuk mendeteksi kesalahan dan iringan aman mereka, untuk menghindari situasi seperti itu.

1. Alat JavaScript


Coba / tangkap balok


Fungsi yang mungkin gagal dapat dibungkus dalam blok coba / tangkap. Pertama, program mencoba mengeksekusi kode di blok try. Jika karena alasan tertentu eksekusi kode rusak, program masuk ke blok tangkap, di mana tiga parameter tersedia:

  • nama - nama standar kesalahan;
  • pesan - pesan tentang rincian kesalahan;
  • stack - tumpukan panggilan saat ini di mana kesalahan terjadi.

Yaitu:

try {

   callFunc();

} catch (e) {

   console.log(e.name) // ReferenceError

   console.log(e.message) // callFunc is not defined

   console.log(e.stack) // ReferenceError: callFunc is not defined at window.onload

}

Untuk pengembang, yang utama adalah bahwa program akan dapat melanjutkan eksekusi setelah catch block. Dengan demikian, interaksi pengguna tidak akan terganggu.

Menggunakan blok coba / tangkap, Anda juga dapat menyebabkan kesalahan Anda sendiri, misalnya, saat memeriksa data:

const user = {

  name : «Mike»

};

try {

   if (!user.age) throw new SyntaxError(«User age is absent!»);

} catch (e) {

   console.log(e.name) // SyntaxError

   console.log(e.message) // User age is absent!

   console.log(e.stack) // SyntaxError: User age is absent! at window.onload

}

Akhirnya, Anda dapat memperpanjang pernyataan ini dengan satu blok lagi - akhirnya, yang selalu dieksekusi: baik dalam kasus di mana tidak ada kesalahan dalam percobaan, dan dalam kasus kontrol dilewatkan ke blok tangkap:

try {

   callFunc();

} catch (e) {

   console.log(e)

} finally {

   ...

}

Kadang-kadang mereka menggunakan pernyataan try / akhirnya (tanpa tangkapan) sehingga Anda dapat terus menggunakan kode tanpa menangani kesalahan tertentu.

Window.oner event


Seringkali berguna untuk mengetahui bahwa skrip pada halaman telah rusak, bahkan jika program telah rusak dan sesi pengguna telah berakhir dengan tidak berhasil. Biasanya informasi ini kemudian digunakan dalam sistem logging kesalahan.

Objek jendela global memiliki peristiwa onerror ( gunakan dengan hati-hati: implementasinya mungkin berbeda di browser yang berbeda! ):

window.onerror = function(message, url, line, col, error) {

   console.log(`${message}\n  ${line}:${col}  ${url}`);

};

Jika Anda menempatkan kode ini di awal skrip atau memuatnya di skrip terpisah di tempat pertama, maka untuk setiap kesalahan di bawah ini pengembang akan tersedia informasi rinci tentang itu.

Namun, informasi lengkap hanya tersedia untuk skrip yang telah diunduh dari domain yang sama. Jika skrip rusak dimuat dari domain lain, window.onerror akan berfungsi, tetapi tidak akan ada detail kesalahan.

Komponen kerangka kerja


Beberapa kerangka kerja JS ( React , Vue) menawarkan solusi penanganan kesalahan mereka sendiri. Misalnya, Bereaksi akan dapat menggambar tata letak khusus di lokasi blok tempat kesalahan terjadi:

class ErrorBoundary extends React.Component {

   constructor(props) {

       super(props);

       this.state = { hasError: false };

   }

   static getDerivedStateFromError(error) {

       //    ,      UI.

       return { hasError: true };

   }

   componentDidCatch(error, errorInfo) {

       //           

       logErrorToMyService(error, errorInfo);

   }

   render() {

       if (this.state.hasError) {

           //    UI  

           return <h1>-   .</h1>;

       }

       return this.props.children;

   }

}

<ErrorBoundary>

   <MyWidget />

</ErrorBoundary>

Bahkan, komponen Bereaksi dibungkus dalam komponen khusus yang menangani kesalahan. Ini mirip dengan fungsi pembungkus dengan try / catch construct.

2. Alat perakitan proyek


Skrip JS modern biasanya dibuat transparan. Artinya, pengembangan dilakukan dengan menggunakan standar ES terbaru. Dan kemudian kode pengembang menggunakan pembangun proyek (seperti Webpack) dikonversi menjadi kode yang akan dijamin bekerja di sejumlah browser yang dipilih.

Pada tahap build, kode diperiksa untuk sintaks yang benar. Braket terbuka atau penunjukan yang salah dari bidang kelas akan segera menyebabkan kesalahan selama perakitan, dan bundel tidak akan dirakit. Pengembang harus segera memperbaiki kesalahan tersebut agar dapat terus bekerja.

Juga, kolektor dapat menyarankan bahwa beberapa bagian kode tidak digunakan ketika menjalankan program. Mungkin ini akan mendorong pengembang untuk memikirkan studi yang lebih dalam dari kode, yang secara tidak langsung dapat mempengaruhi identifikasi kesalahan baru.

3. Pengujian


Cara lain untuk mencegah kesalahan dalam kode adalah dengan mengujinya. Ada alat di frontend untuk penggunaan tes unit yang efektif. Biasanya, kerangka kerja seperti Jest, Karma, Mocha, Jasmine digunakan. Bersamaan dengan kerangka kerja pengujian, mereka sering menggunakan ekstensi seperti Enzim, React Testing Library, Sinon, dan lainnya, yang memungkinkan pengujian pengayaan dengan bantuan mengejek, fungsi mata-mata dan alat-alat lainnya.

Saat mencari kesalahan, tes terutama berguna untuk memuat berbagai data yang dapat menyebabkan kesalahan eksekusi. Jadi, kode berikut akan lulus validasi sintaks dan berfungsi seperti yang diharapkan:

const func = (data) => {

   return JSON.parse(data)

}

func('{«a»:1}')

Namun, itu akan rusak jika Anda memberikan nilai yang salah:

func() // Uncaught SyntaxError: Unexpected token u in JSON at position 0.


Kode ini juga melewati validasi selama perakitan:

const obj = {

   outer : {

       last : 9

   }

}

if (obj.outer.inner.last) {

   console.log(«SUCCESS»)

}

Namun, itu juga akan rusak selama eksekusi. Setelah pengujian, pengembang mungkin akan melakukan pemeriksaan tambahan:

if (obj.outer?.inner?.last) {

   console.log(«SUCCESS»)

}

Seringkali, kesalahan seperti itu terjadi ketika menerima data dari server (misalnya, dengan permintaan AJAX) dengan analisis selanjutnya. Menguji kode memungkinkan Anda untuk mengidentifikasi dan menghilangkan kasus sebelumnya di mana kode dapat rusak selama eksekusi di browser klien.

4. Penebangan


Misalkan kita telah mengambil semua langkah yang mungkin untuk mencegah kesalahan selama pengembangan dan perakitan proyek. Namun, kesalahan masih dapat menyusup ke kode produktif. Kita perlu entah bagaimana mencari tahu tentang keberadaan mereka dan segera mengambil tindakan korektif. Meminta pengguna untuk membuka konsol browser dan mengambil tangkapan layar bukan pilihan terbaik. Karenanya, ada baiknya untuk menghubungkan kesalahan logging ke proyek.

Artinya sederhana: untuk setiap peristiwa window.oner atau setiap transisi dari eksekusi kode ke blok catch, permintaan AJAX sederhana dibuat ke alamat server yang dialokasikan secara khusus, di tubuh di mana informasi tentang kesalahan diletakkan. Selanjutnya, Anda akan memerlukan alat yang akan dengan cepat memberi tahu dukungan teknis dan pengembang tentang adanya kesalahan baru dan memungkinkan Anda untuk bekerja secara efektif dengan mereka. Alat paling populer dari frontend ini adalah Sentry.

Sistem logging sentry memungkinkan Anda untuk mengumpulkan, mengelompokkan, menyajikan kesalahan secara real time. Ada majelis untuk berbagai bahasa, termasuk JavaScript. Proyek ini menyediakan akses berbayar dengan fitur-fitur canggih untuk bisnis, namun, Anda dapat mencoba fitur utamanya pada akun uji gratis.

Sentry dapat dihubungkan baik secara langsung dalam file HTML, dan dalam komponen yang dieksekusi pada salah satu kerangka kerja populer: React, Vue, Angular, Ember dan lainnya.

Untuk menghubungkan kapabilitas pencatatan secara langsung di browser di bagian tersebut, muat skrip:

<script

   src=«https://browser.sentry-cdn.com/5.13.0/bundle.min.js»

   integrity=«sha384-ePH2Cp6F+/PJbfhDWeQuXujAbpil3zowccx6grtsxOals4qYqJzCjeIa7W2UqunJ»

   crossorigin="anonymous"></script>


Selanjutnya, dalam kode JS, kami menginisialisasi:

Sentry.init({

   dsn: 'https://<your account key here>@sentry.io/<your project id here>'

});

Semua. Jika dan ketika kesalahan terjadi pada kode di bawah baris ini, Sentry akan mencatatnya. Log akan direkam bahkan ketika kesalahan terjadi karena kesalahan skrip dari domain lain:



Sentry memiliki banyak kesempatan untuk menganalisis berbagai pesan kesalahan dan mengonfigurasi pemberitahuan. Dimungkinkan juga untuk mengelompokkan log kesalahan dengan rilis produk Anda:

Sentry.init({

   dsn: 'https://<your account key here>@sentry.io/<your project id here>',

   release: '2020.03.06.1'

});

Menggunakan Sentry, statistik dapat digunakan untuk mentransfer konteks kesalahan, misalnya, informasi pelanggan, sidik jari, tingkat kesalahan (fatal, kesalahan, peringatan, info, debug), dan tag.

Dimungkinkan untuk merekam peristiwa pengguna dalam statistik. Misalnya, Anda dapat mengatur pelacakan untuk mengubah ukuran jendela browser atau membuat permintaan AJAX. Sentry juga memiliki widget sendiri dengan jendela umpan balik, yang dapat ditampilkan kepada pengguna jika terjadi kesalahan. Ini akan memberikan informasi tambahan untuk menyelidiki keadaan kesalahan.

Untuk menggunakan Sentry beserta kerangka kerjanya, cukup instal paket dan sambungkan:

# Using yarn

yarn add @sentry/browser

# Using npm

npm install @sentry/browser


Kami melakukan inisialisasi dalam skrip utama proyek (untuk React and Angular):

import * as Sentry from «@sentry/browser»;

Sentry.init({ dsn: 'https://<your account key here>@sentry.io/<your project id here>' });


Untuk Vue dan Ember, kami melewati garis konfigurasi lain yang diperlukan:

# Vue

Sentry.init({

   dsn: '<your account key here>@sentry.io/<your project id here>',

   integrations: [new Integrations.Vue({Vue, attachProps: true})],

});

# Ember

Sentry.init({

   dsn: '<your account key here>@sentry.io/<your project id here>',

   integrations: [new Integrations.Ember()]

});

Paket integrasi diinstal secara terpisah:

# Using yarn

yarn add @sentry/integrations

# Using npm

npm install @sentry/integrations

Untuk mencegah konflik dan duplikasi informasi saat menghubungkan banyak skrip dalam satu proyek, Sentry memungkinkan Anda membuat klien terpisah untuk setiap inisialisasi logging:

import { BrowserClient } from «@sentry/browser»;

const client = new BrowserClient({

   dsn: '<your account key here>@sentry.io/<your project id here>',

});

client.captureException(new Error('example'));

Situs web proyek memiliki dokumentasi terperinci dengan contoh penggunaan: https://docs.sentry.io .

Artikel ini disiapkan dengan dukungan platform cloud Mail.ru Cloud Solutions .

Apa lagi yang harus dibaca pada topik:

  1. Reactable React Components: Cara Berhenti Menulis yang Sama .
  2. Cara menghindari kesalahan saat mengembangkan pada Bereaksi .
  3. - .

All Articles