it-swarm-id.com

Apa cara yang benar untuk penanganan pengecualian?

Di Joomla core saya menemukan masih banyak panggilan seperti ini:

    // Check for errors.
    if (count($errors = $this->get('Errors')))
    {
        JError::raiseError(500, implode("\n", $errors));
        return false;
    }

Tetapi JError sudah tidak digunakan lagi sejak Platform merilis 12.1. Jadi bagaimana saya harus menggunakan pengecualian standar PHP.

20
Harald Leithner

Seperti @DmitryRekun berkata, diskusi yang bagus adalah di sini . Bagian penting untuk dipertimbangkan dalam semua ini adalah jenis kesalahan apa yang Anda miliki?

Ada dua jenis kesalahan:

  1. Dapat dipulihkan
  2. Tidak dapat dipulihkan.

Perbedaannya saya cenderung menyimpulkan sebagai berikut:

Can I still show the page that was requested, even though this error occurred?
  • Iya nih? - Dapat dipulihkan
  • Tidak? - Tidak bisa dipulihkan

Sekarang kita tahu apa yang sedang kita hadapi. Apa yang harus kamu lakukan

Jika kesalahan tidak dapat dipulihkan, Anda ingin mengarahkan mereka ke halaman kesalahan alih-alih melanjutkan ke halaman yang diminta . Itu sesederhana berikut ini:

throw new Exception(JText::_('COM_MYCOMP_ERROR_MESSAGE_NOT_FOUND'), 404);

Exception adalah kelas yang mengambil dua parameter, pesan dan kode. Disarankan untuk mencoba menggunakan HTTP Response Codes jika sesuai dengan skenario Anda.

Jika kesalahan dapat dipulihkan, Anda mungkin hanya ingin menampilkan pesan kembali ke pengguna akhir sambil tetap menunjukkan kepada mereka halaman yang mereka minta. Ini biasanya berarti bahwa Anda harus 'mengirim pesan' untuk aplikasi:

JFactory::getApplication()->enqueueMessage($error, 'error');

enqueueMessage mengambil dua parameter, pesan kesalahan dan jenis pesan. Info lebih lanjut di sini (di bagian bawah).


Ada juga situasi ketiga yang terjadi cukup sering bagi saya setidaknya. Joomla akan memberikan pengecualian untuk kesalahan yang berbeda (seperti kesalahan permintaan basis data). Ini berarti bahwa Joomla berpikir bahwa kesalahan ini tidak dapat dipulihkan. Namun, Anda mungkin ingin melanjutkan. (Misalnya, jika saya mengubah tabel tentang pembaruan ekstensi saya, saya bisa menjalankan query ALTER, yang akan mengeluarkan pengecualian jika tabel sebelumnya telah diubah.)

Dalam hal ini, Anda ingin membungkus kode yang mungkin membuang pengecualian di bagian coba ... catch:

try {
    // exception generating code
    throw new Exception('Normally you would have other code that calls a class that throws the exception', 500);
} catch (Exception $e) {
    $msg = $e->getMessage(); // Returns "Normally you would have other code...
    $code = $e->getCode(); // Returns '500';
    JFactory::getApplication()->enqueueMessage($msg, 'error'); // commonly to still display that error
}

Perhatikan bahwa apa yang Anda lakukan adalah "menangkap" kesalahan yang tidak dapat dipulihkan dan memaksa sistem untuk memulihkan dan terus menampilkan halaman yang diminta.


Tambahkan semua ini dan kasing Anda harus merupakan kesalahan yang tidak dapat dipulihkan. (Saya tahu ini karena Anda memiliki 'return false' setelahnya, jadi Anda kemungkinan tidak berencana untuk melanjutkan dan menyerah pada fungsi.)

Jadi saya akan menulis ulang ini sebagai berikut:

// Check for errors.
if (count($errors = $this->get('Errors')))
{
    throw new Exception(implode("\n", $errors), 500);
    return false; // you can remove this too, technically since the exception will take you out of this function.
}
17
David Fritsch

Inilah cara saya mengelola kesalahan.

Lihat atau Pengontrol

try
{
    $this->item = $this->get('Item');
}
catch (Exception $e)
{
    if ($e->getCode() == 404)
    {
        // Not found
        throw new Exception($e->getMessage(), 404);
    }

    // Generic errors
    JFactory::getApplication()->enqueueMessage(JText::_('COM_MYCOMP_ERROR_OCCURRED'), 'error');
}

Jadi jika saya mendapatkan kode 404 dari Model saya (misalnya):

if (empty($data))
{
    throw new Exception(JText::_('COM_MYCOMP_ERROR_MESSAGE_NOT_FOUND'), 404);
}

Lalu saya menangkapnya di tampilan atau pengontrol dan melemparkan satu Pengecualian lagi yang akan ditangani Joomla dan akan menampilkan 404 halaman. Untuk yang lain saya hanya menunjukkan beberapa pesan kesalahan umum kepada pengguna.

Juga baca diskusi menarik tentang penanganan kesalahan ini.

12
Dmitry Rekun

Sebagian besar blok kode seperti ini dapat dengan mudah diganti dengan enqueueMessage karena tidak benar-benar bekerja pada kesalahan dan hanya menggunakan JError untuk mencetaknya.

// Check for errors.
if (count($errors = $this->get('Errors'))) {
    foreach($errors as $error) {
        JFactory::getApplication()->enqueueMessage($error, 'error');
    }
}
4
Spunkie