Каков правильный способ обработки исключений?

В ядре Joomla я нахожу еще много таких вызовов:

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

Но JError устарел с момента выпуска платформы 12.1. Итак, как я должен использовать стандартные исключения PHP.

19 голосов | спросил Harald Leithner 23 PMpWed, 23 Apr 2014 23:45:09 +040045Wednesday 2014, 23:45:09

3 ответа


16

Как сказал @DmitryRekun, хорошее обсуждение здесь . Ключевая часть, которую нужно учитывать во всем этом, - это какая у вас ошибка?

Существует два типа ошибок:

  1. Извлекаемые
  2. неустранимый.

Разница, как правило, сводится к следующему:

Can I still show the page that was requested, even though this error occurred?
  • Да? - Восстанавливаемый
  • Нет? - Невосстановимый

Теперь, когда мы знаем, с чем имеем дело. Что вы должны делать?

Если ошибка невосстановима, вы хотите перенаправить их на страницу с ошибкой , а не продолжить поисковую страницу . Это так просто, как следующее:

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

Exception - это класс, который принимает два параметра, сообщение и код. Рекомендуется использовать коды ответов HTTP , если они соответствуют вашему сценарию.

Если ошибка будет восстановлена, вы, скорее всего, просто захотите отобразить сообщение для конечного пользователя, показывая им страницу, которую они запросили. Обычно это означает, что вы должны «поставить в очередь» сообщение для приложения:

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

enqueueMessage принимает два параметра, сообщение об ошибке и тип сообщения. Подробнее здесь (внизу).


Существует также третья ситуация, которая встречается довольно часто для меня, по крайней мере. Joomla будет генерировать исключения для различных ошибок (например, ошибка запроса базы данных). Это означает, что Joomla считает, что эта ошибка невосстанавливается. Тем не менее, вы можете продолжить в любом случае. (Например, если я изменяю таблицу при обновлении моего расширения, я могу просто запустить запрос ALTER, который выдает исключение, если ранее таблица была изменена.)

В этом случае вы хотите обернуть код, который может вызвать исключение в разделе try ... 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
}

Обратите внимание, что то, что вы делаете, это «ловить» неустранимую ошибку и принудительно восстановить систему и продолжить показ запрошенной страницы.


Добавьте все это, и ваш случай должен быть неустранимой ошибкой. (Я знаю это, потому что после этого вы возвращаете false, поэтому вы, вероятно, не планируете продолжать и отказываетесь от функции.)

Таким образом, я бы переписал это следующим образом:

// 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.
}
ответил David Fritsch 25 AMpFri, 25 Apr 2014 02:09:47 +040009Friday 2014, 02:09:47
12

Вот как я управляю ошибками.

Просмотреть или контроллер

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

Итак, если я получаю код 404 из моей Модели (например):

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

Затем я поймаю его в представлении или контроллере и выброшу еще одно исключение, которое Joomla будет обрабатывать и отобразит страницу 404. Для любого другого я просто показываю пользователю общее сообщение об ошибке.

Также читайте эту интересную дискуссию об обработке ошибок.

ответил Dmitry Rekun 24 AMpThu, 24 Apr 2014 00:09:00 +040009Thursday 2014, 00:09:00
4

Большинство таких блоков кода можно просто заменить на enqueueMessage, поскольку они фактически не действуют на ошибку и просто используют JError, чтобы распечатать их.

// Check for errors.
if (count($errors = $this->get('Errors'))) {
    foreach($errors as $error) {
        JFactory::getApplication()->enqueueMessage($error, 'error');
    }
}
ответил Spunkie 23 PMpWed, 23 Apr 2014 23:52:58 +040052Wednesday 2014, 23:52:58

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132