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


20

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ı. Öyleyse standart PHP istisnalarını nasıl kullanmalıyım.


1
Fark JError'dan PHP Hatalarına geçiyor maalesef tek bir tıklama işlemi değil. Bu nedenle, bir istisna alacağınızdan eminseniz, aşağıdaki yanıtta olduğu gibi bir dene / yakala ifadesi yapın. Bir JError alacağınızdan eminseniz, yukarıdakine benzer bir kod yapmanız gerekir :)
George Wilson

Yanıtlar:


17

@ DmitryRekun'un dediği gibi, burada iyi bir tartışma var . 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
  • Yok hayır? - Kurtarılamaz

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

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

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

Exceptionileti ve kod olmak üzere iki parametre alan bir sınıftır. Senaryonuza uyuyorsa HTTP Yanıt Kodlarını kullanmaya çalışmanı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');

enqueueMessagehata 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ın güncelleştirilmesiyle ilgili bir tabloyu değiştirirsem, ALTERsorguyu çalıştırabilirim; bu, tablo önceden değiştirilmişse bir istisna atar.)

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.
}

İyi cevap! Ama güvenmiyorum $this->get('Errors')çünkü aynı zamanda kullanımdan kaldırıldı.
Dmitry Rekun

Başarısız iddialar hakkında herhangi bir yorum, yani dahili hatalar var mı? Programın başarısız bir iddiayla hemen ölmesini istiyorum - bunu yapmanın Joomla'ya özgü bir yolu var mı? Eğer Şu anda bir assert işleyicisi kayıt JDEBUGolduğunu true.
Olle Härstedt

12

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

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

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 hataları ele alma hakkındaki bu ilginç tartışmayı da okuyun .


4

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

// Check for errors.
if (count($errors = $this->get('Errors'))) {
    foreach($errors as $error) {
        JFactory::getApplication()->enqueueMessage($error, 'error');
    }
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.