Skip to content

Perbaikan penanganan error validasi pada form create dan edit master bantuan - #1289

Open
habibie11 wants to merge 1 commit into
rilis-devfrom
fix-bantuan-1278
Open

habibie11 wants to merge 1 commit into
rilis-devfrom
fix-bantuan-1278

Conversation

@habibie11

Copy link
Copy Markdown
Contributor

issue #1278

🎯 Deskripsi

Pull request ini memperbaiki penanganan pesan kesalahan (error handling) pada formulir Tambah Bantuan (/master/bantuan/create) dan Ubah Bantuan (/master/bantuan/{id}/edit).

Sebelum perbaikan ini, ketika pengiriman form gagal divalidasi oleh API upstream (API-Database-Gabungan) dengan status HTTP 422 dan respons JSON:

{
    "success": false,
    "message": "Validation failed",
    "errors": {
        "nama": [
            "Format isian nama tidak valid."
        ]
    }
}

SweetAlert hanya menampilkan teks generik "Validation failed" dari response.message atau xhr.responseJSON.message. Pengguna tidak mendapatkan informasi spesifik mengenai field mana yang salah atau apa aturan validasi yang dilanggar (misalnya aturan regex pada nama bantuan). Selain itu, pemanggilan langsung xhr.responseJSON.message berisiko memicu TypeError di JavaScript apabila xhr.responseJSON tidak terdefinisi (misal akibat kegagalan jaringan atau server mengembalikan respons HTML).

Perbaikan ini menambahkan fungsi showErrorAlert(response, fallbackMessage) pada view create.blade.php dan edit.blade.php yang secara cerdas:

  1. Mengekstrak seluruh pesan kesalahan dari objek errors.
  2. Menampilkan pesan secara langsung jika hanya terdapat 1 error validasi.
  3. Menampilkan daftar rapi (bullet list) berformat HTML yang telah di-escape secara aman jika terdapat lebih dari 1 error validasi.
  4. Menyediakan fallback yang aman ke data.message atau pesan default bila errors tidak tersedia, serta mencegah terjadinya TypeError pada JavaScript.

🛠️ Perubahan yang Dilakukan

1. resources/views/master/bantuan/create.blade.php

Fix — Penanganan error validasi dan ekstraksi pesan errors pada form create:

  • Menambahkan fungsi showErrorAlert(response, fallbackMessage).
  • Memperbarui penanganan respons pada AJAX success (kondisi response.success != true) dan error untuk memanggil showErrorAlert().
+           function showErrorAlert(response, fallbackMessage) {
+               let data = response;
+               if (typeof data === 'string') {
+                   try {
+                       data = JSON.parse(data);
+                   } catch (e) {
+                       data = null;
+                   }
+               }
+
+               let errorList = [];
+               if (data && data.errors) {
+                   if (Array.isArray(data.errors)) {
+                       errorList = data.errors;
+                   } else if (typeof data.errors === 'object') {
+                       Object.values(data.errors).forEach(function(err) {
+                           if (Array.isArray(err)) {
+                               errorList.push(...err);
+                           } else if (typeof err === 'string') {
+                               errorList.push(err);
+                           }
+                       });
+                   } else if (typeof data.errors === 'string') {
+                       errorList.push(data.errors);
+                   }
+               }
+
+               if (errorList.length > 1) {
+                   let escapeHtml = function(text) {
+                       let div = document.createElement('div');
+                       div.textContent = text;
+                       return div.innerHTML;
+                   };
+                   Swal.fire({
+                       title: 'Error!',
+                       html: '<ul style="text-align: left; margin: 0; padding-left: 20px;">' +
+                           errorList.map(function(err) {
+                               return '<li>' + escapeHtml(err) + '</li>';
+                           }).join('') + '</ul>',
+                       icon: 'error'
+                   });
+               } else if (errorList.length === 1) {
+                   Swal.fire({
+                       title: 'Error!',
+                       text: errorList[0],
+                       icon: 'error'
+                   });
+               } else {
+                   let message = (data && data.message) ? data.message : (fallbackMessage || 'Terjadi kesalahan sistem');
+                   Swal.fire({
+                       title: 'Error!',
+                       text: message,
+                       icon: 'error'
+                   });
+               }
+           }
...
                                 if (response.success == true) {
                                     ...
                                 } else {
-                                    Swal.fire(
-                                        'Error!',
-                                        response.message,
-                                        'error'
-                                    )
+                                    showErrorAlert(response);
                                 }
                             },
                             error: function(xhr, ajaxOptions, thrownError) {
-                                Swal.fire(
-                                    'Error!',
-                                    xhr.responseJSON.message,
-                                    'error'
-                                )
+                                showErrorAlert(xhr.responseJSON || xhr.responseText, thrownError);
                             }

2. resources/views/master/bantuan/edit.blade.php

Fix — Penanganan error validasi dan ekstraksi pesan errors pada form edit:

  • Menerapkan fungsi helper showErrorAlert(response, fallbackMessage) yang sama.
  • Memperbarui callback success (saat response.success != true) dan error pada request AJAX update data bantuan.
+           function showErrorAlert(response, fallbackMessage) {
+               // Fungsi penanganan ekstraksi response.errors ke SweetAlert
+               ...
+           }
...
                                 if (response.success == true) {
                                     ...
                                 } else {
-                                    Swal.fire('Error!', response.message, 'error')
+                                    showErrorAlert(response);
                                 }
                             },
                             error: function(xhr, ajaxOptions, thrownError) {
-                                Swal.fire('Error!', xhr.responseJSON.message, 'error')
+                                showErrorAlert(xhr.responseJSON || xhr.responseText, thrownError);
                             }

3. tests/Feature/MasterBantuanKabupatenTest.php

Test — Penambahan automated feature test untuk view create dan edit bantuan:

  • Memastikan endpoint master/bantuan/create (bantuan.create) dan master/bantuan/{id}/edit (bantuan.edit) dapat diakses oleh user yang terotentikasi.
  • Memastikan kedua view Blade me-render fungsi showErrorAlert dan logika penanganan data.errors.

✅ Test Cases yang Diimplementasikan

  • Ketika form Tambah atau Ubah Bantuan disubmit dan API upstream merespons kegagalan validasi (HTTP 422 dengan pesan "Validation failed"), SweetAlert menampilkan teks pesan error dari properti errors (contoh: "Format isian nama tidak valid."), bukan hanya teks umum "Validation failed".
  • Ketika terdapat lebih dari 1 field yang gagal validasi pada respons errors, SweetAlert menampilkan daftar terstruktur (bulleted list) dari seluruh pesan error yang ada.
  • Karakter khusus pada pesan error di-escape dengan aman menggunakan manipulasi DOM (textContent) sebelum dirender ke dalam HTML SweetAlert untuk mencegah kerentanan XSS.
  • Ketika respons error tidak memiliki properti errors, SweetAlert dengan aman beralih menampilkan data.message atau fallbackMessage tanpa terjadi TypeError: Cannot read properties of undefined (reading 'message').
  • Test otomatis pada tests/Feature/MasterBantuanKabupatenTest.php dieksekusi dengan sukses (2 passed, 9 assertions).

📸 Cara Menjalankan Uji Coba Manual

  1. Pastikan aplikasi OpenKab dan API-Database-Gabungan telah berjalan serta terhubung.
  2. Login ke sistem OpenKab menggunakan akun dengan hak akses Master Data Bantuan.
  3. Buka menu Master Data > Bantuan (/master/bantuan).
  4. Klik tombol Tambah Bantuan (/master/bantuan/create).
  5. Masukkan isian nama program bantuan yang tidak sesuai dengan regex validasi (misalnya menggunakan angka seperti Bantuan 123 atau karakter simbol yang tidak diizinkan).
  6. Lengkapi field lainnya lalu klik tombol Simpan.
  7. Konfirmasi pada modal SweetAlert konfirmasi.
    • Seharusnya: SweetAlert Error menampilkan pesan error spesifik: "Format isian nama tidak valid." (bukan hanya "Validation failed").
  8. Lakukan langkah serupa pada halaman edit (/master/bantuan/{id}/edit).
    • Seharusnya: SweetAlert Error menampilkan pesan error spesifik yang sama dari objek errors.

🤖 Cara Menjalankan Uji Coba Otomatis (Automated Test)

Jalankan perintah berikut di terminal untuk mengeksekusi automated test yang dibuat:

php artisan test tests/Feature/MasterBantuanKabupatenTest.php

Hasil yang diharapkan:

PASS  Tests\Feature\MasterBantuanKabupatenTest
✓ it can access bantuan create and contains show error alert
✓ it can access bantuan edit and contains show error alert

Tests:    2 passed (9 assertions)
Duration: ~3s

📸 Screenshot atau Video

image image

⚠️ Catatan Penting

Perubahan ini sepenuhnya kompatibel ke belakang (backward-compatible). Struktur data yang dikirimkan ke API upstream tidak berubah, dan fungsi ini secara fleksibel dapat membaca berbagai format properti errors baik berupa Object (pemetaan nama field ke array string pesan error khas Laravel ValidationException), Array, maupun String, serta menangani skenario di mana response bukan JSON tanpa menghentikan eksekusi script.

@github-actions

github-actions Bot commented Sep 9, 2026

Copy link
Copy Markdown

🔄 AI PR Review sedang antri di server...

Proses review akan segera dimulai di background — hasil akan muncul sebagai komentar setelah selesai.
Powered by CrewAI · PR #1289

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant