Lebihkan ke Konten Utama

Integrasi Sentry React Native 2026: Panduan Lengkap

Integrasikan sentry react native dari awal hingga akhir dengan panduan kami 2026. Meliputi pengaturan, crash native, peta sumber, kinerja, dan Capgo integrasi untuk

Integrasi Sentry React Native 2026: Panduan Lengkap

Anda telah memiliki aplikasi React Native yang berjalan di lokal, QA telah menyetujui, dan produksi sudah dekat. Kemudian pertanyaan yang jelas muncul: apa yang terjadi ketika aplikasi ini bermasalah di perangkat pengguna?

Tidak ada Sentry, jawaban biasanya buruk. Anda mendapatkan tiket dukungan, tangkapan layar yang kabur, mungkin log konsol dari build dev yang tidak sesuai dengan produksi. Dengan Sentry React Native yang terinstal dengan benar, Anda mendapatkan kesalahan, stack, rilis yang mengirimkannya, dan cukup konteks untuk memperbaiki masalah tanpa menebak. Namun, ada kelemahan Pemasangan dasar adalah bagian yang mudah. Bagian yang menyakitkan datang kemudian: integrasi native, simbolisasi, peta sumber, penamaan rilis, dan menjaga semua itu seimbang ketika model pengiriman Anda termasuk pembaruan langsung.

Sebagian besar panduan berhenti terlalu awal. Konfigurasi yang sebenarnya harus bertahan melalui CI, pembangunan App Store, rilis Android, dan bundle JavaScript yang tidak selalu berasal dari biner asli.

Tabel Konten

Mulai Menggunakan SDK Sentry

Metode tercepat untuk memasukkan Sentry React Native ke dalam aplikasi baru masih menggunakan asisten instalasi. Asisten ini mengelola sebagian besar pengaturan yang berulang dan membawa Anda ke garis dasar yang berfungsi dengan cepat. Hal ini penting karena mengulangi pengaturan instalasi pertama biasanya menyebabkan kesalahan kecil yang tidak Anda sadari sampai terjadi crash produksi pertama.

Apa yang Anda butuhkan sebelum menginstal

Anda perlu lingkungan pengembangan React Native yang normal terlebih dahulu. Node, manajer paket, alat-alat platform untuk iOS dan Android, dan Watchman pada macOS jika itu sudah bagian dari alur kerja Anda. Anda juga perlu akun Sentry dan proyek yang dibuat untuk React Native.

Jika Anda masih mengevaluasi apakah React Native adalah pilihan operasional yang tepat untuk tim Anda, ini Petunjuk React Native untuk bisnis memberikan konteks yang berguna di luar konteks pemasaran seputar perbandingan platform, staf, dan harapan perawatan. Hal ini patut dibaca sebelum Anda mengkomitkan proses pengawasan dan proses rilis seputar kode bersama.

Instal SDK dengan asisten dari root proyek:

npx @sentry/wizard@latest -i reactNative

Asisten ini bertanya beberapa hal yang pengembang seringkali klik terlalu cepat:

  • Pemilihan proyekPilih proyek Sentry yang sebenarnya yang Anda rencanakan untuk digunakan di produksi, bukan sandbox sementara yang Anda lupakan untuk diperbarui kemudian.
  • Pengubahan nativeYa, setuju. Pengambilan kesalahan JavaScript saja tidak cukup untuk aplikasi mobile.
  • Fitur opsionalYa, aktifkan apa yang Anda ketahui akan digunakan, tapi jangan mengaktifkan semuanya secara acak pada hari pertama jika tim Anda tidak akan memeriksa data hasilnya.

Melakukan sihir dan memeriksa hasilnya

Setelah sihir selesai, periksa perubahan daripada mengandalkan mereka tanpa memeriksa. Anda seharusnya melihat paket Sentry di package.jsonperubahan native di bawah ios dan androidcontext

Halaman/area: Situs web pemasaran Capgo. Peran: Label UI singkat atau item navigasi. Dilihat di: halaman trust.astro. Kunci pesan `dan` (Dan).

import * as Sentry from '@sentry/react-native';

Sentry.init({
  dsn: 'YOUR_DSN',
});

, dan blok inisialisasi di file entry aplikasi Anda. Contoh inisialisasi biasa seperti ini: DSN ini menginformasikan SDK di mana untuk mengirimkan event. Tatalah sebagai konfigurasi, bukan sebagai item vault rahasia yang harus selalu tidak terlihat. Ini tidak sama dengan token autentikasi. Namun, jaga setup lingkungan Anda tetap bersih dan konsisten sehingga aplikasi Anda mengarah ke proyek Sentry yang tepat di setiap lingkungan.

Aplikasikan pola praktis untuk memuat DSN dari konfigurasi spesifik lingkungan dan inisialisasi Sentry sebelum pohon aplikasi Anda berpohon. Jika Anda juga bekerja melalui proses penyempurnaan startup, panduan ini ke Setup Layar Splash React Native is useful because startup code order often intersects with where teams place Sentry initialization.

Aturan praktis: Inisialisasi Sentry secepat mungkin dalam proses startup aplikasi. Jika Anda menunggu sampai setelah navigasi, autentikasi, atau konfigurasi remote, Anda akan melewatkan kegagalan startup.

Pada tahap ini, jangan mencari kesempurnaan. Tujuan segera adalah sederhana: luncurkan aplikasi, trigger kesalahan JavaScript di artikel ini, dan konfirmasi bahwa event mencapai Sentry. Setelah itu, lapisan native dan rilis menjadi lebih mudah untuk dipahami.

Mengonfigurasi Projek iOS dan Android Native

Pada tahap ini, banyak tim React Native mendapatkan kesan palsu bahwa aplikasi sudah selesai. JavaScript SDK sudah terinstal, event muncul, dan semua orang menganggap pelaporan kegagalan sudah selesai. Tidak. Jika integrasi native dimatikan, beberapa kegagalan yang paling Anda pedulikan tidak akan pernah mencapai Sentry dalam bentuk yang dapat digunakan.

Apa yang berubah pada iOS

Buka projek iOS dan tinjau apa yang berubah. Dalam aplikasi React Native yang sederhana, biasanya berarti perubahan seputar startup aplikasi dan fase pembangunan. Anda sedang mencari hook inisialisasi Sentry dan langkah unggah yang terkait dengan proses pembangunan Anda.

Pada Xcode, periksa tempat-tempat ini:

  • Startup code delegasi aplikasiPerlu inisialisasi native Sentry pada awal peluncuran aplikasi.
  • Build PhasesCari skrip unggah Sentry terkait simbol debug atau pengelolaan map sumber.
  • Pengaturan Build dan perilaku arsip.Simbol file harus dihasilkan dan tersedia selama proses build arsip.

Jika aplikasi Anda menggunakan AppDelegate.mminisialisasi biasanya berada dekat dengan bootstrapping jembatan React Native. Konten file dapat bervariasi tergantung versi React Native, template, dan apakah Anda menggunakan arsitektur baru, jadi jangan salin snippet dari repositori random kecuali yang sesuai dengan bentuk proyek Anda.

Yang penting adalah niat: iOS native crashes memerlukan data simbol, dan aplikasi harus memulai Sentry sebelum crash dapat diamati secara andal.

Jika crash iOS muncul di Sentry dengan frame native yang tidak dapat dibaca, masalah biasanya bukanlah "Sentry yang rusak." Masalahnya adalah unggahan simbol atau matching rilis.

Apakah yang berubah pada Android

Android biasanya menambahkan perubahan pada file Gradle dan kadang-kadang konfigurasi level manifest. Tinjau android/build.gradle, android/app/build.gradledan pengaturan plugin atau task terkait Sentry.

Hal-hal untuk dipastikan:

  1. Plugin Sentry Gradle diterapkan sehingga artefak rilis dapat diproses selama waktu pembangunan.
  2. Penanganan variannya normal jika Anda menggunakan rasa produk atau beberapa jenis pembangunan.
  3. Keluaran ProGuard atau R8 diakui jika rilis Anda menyusut atau mengaburkan code.

Kesalahan Android yang umum adalah menganggap jalankan debug lokal berhasil membuktikan bahwa pengaturan rilis benar. Tidak. Jalur rilis berbeda, terutama setelah minifikasi dan tanda tangan CI masuk ke dalam gambar. Jika tim Anda menjaga bangunan debug, pengujian, QA, dan toko yang terpisah, pemahaman ini tentang Jenis bangunan mobile adalah referensi yang berguna untuk menjaga perilaku pemantauan sejalan dengan setiap variasi bangunan.

Pemeriksaan setup native yang menghemat waktu

Tidak berhenti di “sihir mengubah file.” Pastikan perilaku secara langsung.

Gunakan daftar periksa ini:

  • Simpan bangun iOS secara lokal dan pastikan bangun tidak gagal selama proses simbol.
  • Buat bangun rilis Android dan periksa log CI untuk tugas terkait Sentry.
  • Periksa nama paket dan identifikasi paket yang diatur di Sentry jika Anda mengelola aplikasi yang berbeda di bawah satu organisasi.
  • Pastikan konvensi nama rilis sekarang, sebelum CI mulai mengunggah artefak dengan nama yang tidak konsisten.

Berikut ini yang biasanya tidak berfungsi dengan baik:

Gaya pendekatan Apa yang salah
Tanpa review, mengapa harus percaya sihir? Mengatur native yang berubah ketika React Native atau tooling pembangunan berubah
Melakukan pengujian hanya dalam mode debug Sukses debug menyembunyikan masalah simbolisasi waktu rilis
Menggabungkan langkah unggah manual dan otomatis Artifak mendarat di bawah rilis yang berbeda dan tidak akan cocok dengan event

Setup terbaik adalah yang tidak menarik. Hooks startup native sudah ada, skrip pembangunan berjalan setiap kali, dan nama rilis sudah ditentukan secara konsisten di iOS, Android, dan bundle JavaScript.

Mengautomasi Rilis dan Map Sumber

Jika ada satu tempat di mana setup Sentry React Native runtuh, itu di sini. Tim menginstal SDK, melihat event, dan menunda otomatisasi rilis. Lalu masalah produksi serius datang dan tanda-tanda stack adalah yang termini, rilis hilang, atau unggah map sumber milik bundle yang berbeda.

Unggah map sumber manual terdengar wajar ketika Anda mengirimkan jarang. Namun, dalam prakteknya, mereka gagal karena manusia buruk dalam menjaga buku catatan rilis yang berulang.

Mengapa unggah manual gagal dalam prakteknya

Mode gagal yang dapat diprediksi adalah:

  • Seseorang lupa mengunggah peta Sesudah perbaikan malam hari yang terlambat.
  • File yang diunggah milik komit lain daripada bundle biner atau OTA yang digunakan pengguna.
  • Nama rilis berubah sedikit antara langkah iOS, Android, dan CI.
  • Rebuild terjadi setelah unggah peta dan membuat apa yang Sentry harus mencocokkan menjadi tidak valid.

Itulah mengapa saya tidak merekomendasikan pendekatan “dokumentasikan langkah-langkah di Notion”.

Pendekatan itu berfungsi sampai rilis darurat keluar di bawah tekanan.

Diagram alir tujuh langkah yang menunjukkan proses otomatis mengelola rilis Sentry dan peta sumber untuk React Native.

Proses rilis yang sebenarnya berfungsi dengan baik.

  • ID rilis dihasilkan sekali saja dan digunakan di mana-mana.
  • Langkah-langkah pembangunan, pengemasan, dan unggah terjadi dalam alur yang sama.
  • Peta sumber diunggah dari CIbukan dari laptop pengembang.
  • Aplikasi memulai Sentry dengan string rilis yang sama yang digunakan CI selama unggah.

Poin terakhir itu lebih penting dari yang diharapkan. Anda tidak hanya membutuhkan peta sumber di Sentry. Anda membutuhkan peta sumber yang tepat yang terpasang pada identifikasi rilis yang tepat yang dihasilkan oleh aplikasi pada saat runtime.

Jika tim Anda sudah menerapkan standar otomatisasi mobile, panduan ini tentang alur kerja otomatis pembangunan dan rilis dengan GitHub Actions cocok dengan model operasional yang sama.

Aplikasi CI yang Praktis

Pakai skrip seperti ini di CI dan berikan nilai dari lingkungan pipeline Anda:

#!/usr/bin/env bash
set -euo pipefail

export SENTRY_AUTH_TOKEN="$SENTRY_AUTH_TOKEN"
export SENTRY_ORG="your-org"
export SENTRY_PROJECT="your-project"

RELEASE_NAME="${APP_VERSION}+${GIT_SHA}"

npx sentry-cli releases new "$RELEASE_NAME"

npx react-native bundle \
  --platform ios \
  --dev false \
  --entry-file index.js \
  --bundle-output ./dist/main.jsbundle \
  --sourcemap-output ./dist/main.jsbundle.map

npx sentry-cli releases files "$RELEASE_NAME" upload-sourcemaps ./dist \
  --rewrite \
  --strip-prefix "$(pwd)"

npx sentry-cli releases finalize "$RELEASE_NAME"

Anda memerlukan untuk menyesuaikan perintah bundel untuk Android, dan banyak tim membagi pekerjaan spesifik platform daripada memaksa satu skrip untuk melakukan kedua hal. Itu tidak apa-apa. Yang penting adalah konsistensi.

Disciplin Rilis Lebih Baik dari Skrip yang Cerdik. Pilih satu konvensi nama, masukkan ke dalam aplikasi pada saat pembangunan, dan jangan biarkan unggahan ad hoc lokal bersaing dengan CI.

Untuk React Native, saya lebih suka menyimpan string rilis di satu lokasi konfigurasi yang dibangun dan membacanya selama Sentry.init():

Sentry.init({
  dsn: Config.SENTRY_DSN,
  release: Config.SENTRY_RELEASE,
  dist: Config.SENTRY_DIST,
});

Hasilnya sederhana. Ketika suatu event datang, Sentry dapat menerjemahkan frame yang di-minifikasi ke code yang Anda kirim, bukan code yang Anda pikir Anda kirim.

Perekaman Data Kinerja dan Event Kustom

Kecelakaan memberitahu Anda apa yang rusak. Perekaman kinerja memberitahu Anda apa yang dirasakan pengguna sebelum mereka menyerah.

Laporan umum terdengar seperti ini: “Dashboard lambat.” Itu tidak cukup untuk debugging. Lambat di mana? Pada navigasi? Saat mengambil data? Saat mengrender grafik yang berat? Sentry menjadi berguna di sini ketika Anda berhenti menganggapnya seperti kotak surat kesalahan dan mulai menginstrumentasi perilaku aplikasi.

Seorang pengembang perangkat lunak yang sedang mengetik di laptop dengan grafik visualisasi data yang ditampilkan di monitor latar belakang.

Mengikuti jejak lambat daripada menebak

Mulai dengan mengaktifkan tracing kinerja pada inisialisasi Anda. Strategi pengambilan contoh yang tepat bergantung pada lingkungan dan toleransi volume Anda, tetapi strukturnya seperti ini:

Sentry.init({
  dsn: Config.SENTRY_DSN,
  tracesSampleRate: 1.0,
});

Jika Anda menggunakan React Navigation, hubungkan integrasi sehingga transisi layar menghasilkan data tracing. Kemudian, reproduksi keluhan pada perangkat fisik, bukan hanya simulator. Simulator menyembunyikan jenis kelembaban yang pengguna perhatikan.

Contoh dashboard yang berguna:

  1. Pengguna membuka dashboard utama setelah login.
  2. Navigation selesai, tetapi konten muncul terlambat.
  3. Tracing menunjukkan transaksi layar yang lama.
  4. Span anak menunjukkan satu API permintaan dan satu jalur render yang mahal.
  5. Anda memperbaiki jalur render, kirim lagi, dan bandingkan bentuk tracing baru.

Itu lebih baik daripada berargumen dari perasaan hati.

Untuk tim yang berpikir luas tentang pola monitoring webview atau aplikasi hybrid, tulisan ini tentang pengawasan kinerja pada proyek Capacitor patut dibaca karena mindset operasionalnya sama meskipun stacknya berbeda.

Menambahkan konteks yang berguna pada kesalahan

Data kinerja menjadi lebih berguna ketika event membawa konteks bisnis. Bukan metadata yang hanya untuk memuaskan. Cukup untuk menjawab siapa yang terpengaruh, layar apa yang mereka gunakan, dan apa yang terjadi sebelum gagal.

Gunakan alat-alat ini dengan sengaja:

  • Konteks pengguna dengan Sentry.setUser() agar dukungan dapat menghubungkan laporan ke akun yang terpengaruh tanpa harus mencari jawaban secara tebak-tebakan.
  • Jejak-jejak untuk aksi seperti menekan tombol submit, membuka modal, atau memulai sinkronisasi.
  • Tag-tag kustom untuk dimensi seperti jenis rencana, status flag fitur, atau API wilayah.
  • Kesalahan yang tertangkap dengan konteks tambahan ketika Anda menangkap dan memulihkan atau menampilkan gagal yang dikendalikan.

Contoh:

Sentry.setUser({
  id: user.id,
  email: user.email,
});

Sentry.addBreadcrumb({
  category: 'navigation',
  message: 'Opened dashboard screen',
  level: 'info',
});

try {
  await loadDashboard();
} catch (error) {
  Sentry.captureException(error, {
    tags: { screen: 'dashboard' },
    extra: { widget: 'balance-summary' },
  });
}

Jejak breadcrumb seringkali menjadi perbedaan antara “pengguna mengatakan aplikasi membeku” dan “aplikasi gagal setelah membuka dashboard, memulai sinkronisasi, dan mencoba permintaan yang sudah ketinggalan.”

Jika instrumen kustom gagal, biasanya gagal karena terlalu berisik. Jangan tangkap setiap tekanan tombol di aplikasi selamanya. Tangkap batasan, transisi keadaan, dan operasi yang penting saat debugging. Cukup konteks untuk menjelaskan event. Tidak cukup untuk tenggelamkannya.

Verifikasi dan Mengatasi Masalah Integrasi

Anda harus memverifikasi Sentry sebelum mengirimkan, setelah perubahan pipeline build, dan setelah SDK diperbarui. “Aplikasi berfungsi beberapa bulan yang lalu” bukanlah tes yang bermakna.

Cara yang paling bersih adalah dengan memicu gagal terkendali untuk jalur JavaScript dan native, kemudian inspeksi bagaimana mereka tiba di Sentry.

Seorang pengembang perangkat lunak pria menulis code di monitor komputer dengan daftar checklist integrasi uji coba di atas meja.

Memicu Event Uji Coba dengan Aman

Untuk kesalahan JavaScript, tambahkan tombol sementara di layar produksi:

<Button
  title="Trigger JS Error"
  onPress={() => {
    throw new Error('Test JavaScript Sentry error');
  }}
/>

Untuk kecenderungan kecuali yang tidak akan membuat aplikasi jatuh:

<Button
  title="Capture Exception"
  onPress={() => {
    Sentry.captureException(new Error('Handled Sentry test error'));
  }}
/>

Pengujian kecelakaan native harus dilakukan dengan hati-hati dan hanya dalam build pengembangan atau QA yang dikendalikan. Metode helper yang tepat tersedia dapat bervariasi tergantung pada versi SDK dan pengaturan platform, jadi saya lebih suka menggunakan utilitas kecelakaan native yang terdokumentasi SDK ketika ada daripada membuat jalur kecelakaan sendiri.

Apa yang harus diperiksa di UI Sentry

Ketika event muncul, periksa lebih dari judul.

Periksa bidang-bidang berikut:

  • Platform dan mekanisme. Ini membantu membedakan kesalahan JS dari crash native.
  • Rilis dan distribusi. Jika mereka kosong atau salah, peta sumber dan simbolisasi akan berubah.
  • Frame stack. Lokasi sumber yang dapat dibaca harus muncul untuk peta JavaScript yang diunggah dengan benar.
  • Breadcrumbs dan tag. Pastikan konteks kustom Anda telah sampai.
  • Lingkungan. Pastikan event pengembangan dan produksi tidak dicampur menjadi satu aliran.

Jika sebuah event native datang tetapi memiliki symbolikasi yang buruk, jangan terus-menerus mengatur aplikasi code. Biasanya masalah ini adalah masalah artifact build.

Masalah Umum Pemecahan Masalah Sentry React Native

Gejala Penyebab Paling Mungkin Pemecahan Masalah
JavaScript error datang, tetapi jejak kotoran adalah minified Map sumber tidak diunggah untuk rilis yang sesuai Verifikasi CI unggah map setelah bundling dan bahwa release in Sentry.init() cocok dengan rilis yang diunggah secara tepat
Kecelakaan native tidak muncul Hook native SDK hilang atau tidak diinisialisasi pada awalnya Periksa kembali pengaturan native iOS dan Android, lalu tes dengan jalur crash native yang dikendalikan dalam build QA
Pita native iOS tidak dapat dibaca Simbol debug tidak diunggah atau tidak terkait dengan build yang tepat Konfirmasi bahwa build arsip menghasilkan simbol dan langkah unggah berjalan selama CI atau aliran Xcode arsip
Behavior release Android berbeda dari debug Pengurangan atau pengaburan mengubah jalur artefak release Ulas tugas Gradle release dan pastikan proses Sentry berjalan untuk varian release
Event muncul di bawah lingkungan yang salah Konfigurasi waktu build mengalir ke lingkungan lain Nilai DSN, lingkungan, release, dan dist terpisah per target build
Breadcrumbs atau data pengguna hilang Konteks ditetapkan terlalu lambat atau dihapus selama perubahan status aplikasi Set user dan tag langsung setelah status autentikasi selesai, dan tambahkan kuki sekitar aliran kritis

Kebiasaan akhir yang menghasilkan adalah menjaga daftar

Integrasi dengan Alur Pembaruan Hidup seperti Capgo

Pembaruan hidup mengubah model rilis.

Jika Sentry masih berpikir hanya dalam hal versi aplikasi asli, Solusinya adalah membuat identitas rilis Sentry mengikuti bundle hidupbukan hanya biner native.

Menyamakan identifikasi rilis dengan bundle hidup

Untuk alur pembaruan hidup, release dan dist sebagai identifikasi waktu eksekusi yang terkait dengan paket JavaScript yang dikirimkan.

Versi aplikasi native masih penting, tetapi tidak cukup sendiri jika bundle dapat berubah secara independen.

  • Gunakan versi aplikasi native sebagai bagian dari nama rilis dasar.
  • Tambahkan versi live update atau identifier paket.
  • Gunakan dist untuk membedakan channel atau rilis spesifik ketika itu sesuai dengan model Anda.
  • Unggah peta sumber untuk setiap bundle live di bawah identifier rilis yang tepat.

Contoh, jika aplikasi Anda memuat metadata update pada startup, inisialisasi Sentry dengan nilai yang dihasilkan dari bundle aktif saat ini, bukan hanya dari konfigurasi build statis.

Sentry.init({
  dsn: Config.SENTRY_DSN,
  release: activeBundle.releaseName,
  dist: activeBundle.channel,
});

Jadi, ketika pengguna mengalami kesalahan pada bundle yang diperbarui secara langsung, Sentry menyelesaikan frame terhadap peta sumber untuk hotfix tersebut bukan bundle toko lama.

Ini penting dengan model kerja OTA apapun. Jika Anda ingin memahami bagaimana potongan-potongan bergerak di balik model pengiriman itu, penjelasan tentang bagaimana update live bekerja di aplikasi __CAPGO_KEEP_0__ how live updates work in Capacitor apps Berikut adalah jenis pandangan operasional yang tim ingin capai ketika mereka kombinasi metadata update dengan tracking rilis:

Gambar dari https://__CAPGO_KEEP_0__.app

Gambar dari capgo.app

Jangan menggunakan string rilis statis yang sama untuk setiap pembaruan penyimpanan. Jika beberapa paket berbagi rilis Sentry yang sama, debugging menjadi spekulasi lagi.


Jika tim Anda mengirimkan perbaikan di luar siklus tinjauan toko aplikasi, Capgo menguntungkan untuk dievaluasi. Ini memberikan tim Capacitor cara yang terstruktur untuk mengirimkan pembaruan hidup, mengarahkan saluran, mengontrol peluncuran, dan pulih dari rilis buruk dengan cepat. Pasang itu dengan penamaan rilis Sentry yang disiplin dan unggah map sumber, dan Anda mendapatkan alur kerja di mana kesalahan masih menunjuk ke code pengguna yang menjalankan.

Pembaruan Hidup untuk Aplikasi Capacitor

Ketika bug layer web masih aktif, kirimkan perbaikan melalui Capgo daripada menunggu hari-hari untuk persetujuan toko aplikasi. Pengguna mendapatkan pembaruan di latar belakang sementara perubahan native tetap dalam jalur tinjauan normal.

Bantuan Manusia dari Martin

Mulai Sekarang

Terbaru dari Blog Kami

Capgo memberikan Anda wawasan terbaik yang Anda butuhkan untuk menciptakan aplikasi mobile yang profesional benar-benar.