web-gelistirme-sc.com

İstisna yönetimi için doğru yol nedir?

Joomla çekirdeğinde hala böyle birçok çağrı buluyorum:

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

Ancak Platformun 12.1 sürümünden bu yana JError kullanımdan kaldırıldı. Standart PHP istisnaları nasıl kullanmalıyım?.

20
Harald Leithner

@DmitryRekun'un dediği gibi, iyi bir tartışma burada . Tüm bunlarda göz önünde bulundurulması gereken anahtar parça ne tür bir hatanız var?

İki tür hata vardır:

  1. Geri alınabilir
  2. Kurtarılamayan.

Farkı şöyle özetliyorum:

Can I still show the page that was requested, even though this error occurred?
  • Evet? - Kurtarılabilir
  • Hayır? - Kurtarılamaz

Şimdi neyle uğraştığımızı biliyoruz. Ne yapmalısın?

Hata düzeltilemezse, istenen sayfaya devam etmek yerine hata sayfasına yönlendirmek istersiniz. Bu, aşağıdakiler kadar basittir:

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

Exception, bir mesaj ve bir kod olmak üzere iki parametre alan bir sınıftır. Senaryonuza uyuyorsa HTTP Yanıt Kodları kullanmanız önerilir.

Hata giderilebilirse, büyük olasılıkla istedikleri sayfayı göstermeye devam ederken son kullanıcıya bir mesaj görüntülemek isteyebilirsiniz. Bu genellikle uygulama için bir mesajı 'sıralamanız' gerektiği anlamına gelir:

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

enqueueMessage hata mesajı ve mesaj türü olmak üzere iki parametre alır. Daha fazla bilgi burada (altta).


En azından benim için oldukça sık görülen üçüncü bir durum daha var. Joomla, farklı hatalar (veritabanı sorgu hatası gibi) için istisnalar atacaktır. Bu, Joomla'nın bu hatanın düzeltilemez olduğunu düşündüğü anlamına gelir. Ancak yine de devam etmek isteyebilirsiniz. (Örneğin, uzantımı güncellerken bir tabloyu değiştirirsem, tablo önceden değiştirilmişse bir istisna atacak olan ALTER sorgusunu çalıştırabilirim.)

Bu durumda, bir try ... catch bölümünde bir istisna oluşturabilecek kodu sarmak istersiniz:

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
}

Yaptığınız şeyin kurtarılamaz hatayı "yakalamak" olduğunu ve sistemi kurtarmaya ve istenen sayfayı göstermeye devam etmeye zorladığını unutmayın.


Tüm bunları toplayın ve durumunuz kurtarılamaz bir hata olmalıdır. (Bunu biliyorum çünkü daha sonra `` yanlış dönüş '' yaptınız, bu yüzden devam etmeyi planlamıyorsunuz ve işlevden vazgeçiyorsunuz.)

Böylece bunu şu şekilde yeniden yazarım:

// 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.
}
18
David Fritsch

İşte bir hatayı nasıl yönettiğimi.

Görünüm veya Denetleyici

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');
}

Yani Modelimden (örneğin) bir 404 kodu alırsam:

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

Sonra onu görünümde veya denetleyicide yakalarım ve Joomla'nın 404 sayfa görüntüleyeceği ve görüntüleyeceği bir istisna daha atarım. Herhangi biri için ben sadece kullanıcıya bazı genel hata mesajı göstermek.

Ayrıca okuma hataları ele alma hakkında bu ilginç tartışma.

12
Dmitry Rekun

Bunun gibi çoğu kod bloğu, aslında hataya etki etmedikleri ve yazdırmak için enqueueMessage kullandıkları için JError ile değiştirilebilir.

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