28  /  331

Исключения

Просмотров: 7780 (Статистика ведётся с 06.02.2017)
Дата последнего изменения: 09.02.2017

В новом ядре используется механизм исключений (exceptions).

Исключительная ситуация (в которой может быть выброшено исключение) - нетипичная ситуация, при которой не имеет смысла продолжать выполнение базового алгоритма.


Примеры

Если пользователь отправил форму с пустым полем Имя, то это - не исключительная ситуация. Это обычная ожидаемая ситуация, которая должна быть обработана соответствующим образом.

Если же при вызове метода API для изменения элемента инфоблока был указан пустой id элемента, то это исключительная ситуация. Она не ожидаема и продолжать изменение элемента не имеет смысла.

Если метод ожидает id пользователя, а вы передаёте строку, то это - исключение, так как метод не знает что делать со строкой в данном случае.

Если метод GetList принимает фильтр timestamp, а разработчик написал tymestamp, то это будет исключением.


Иерархия исключений

Все исключения D7 наследуются от встроенного в PHP класса \Exception, который присутствует в PHP начиная с версии 5.1. У данного класса есть не переопределяемые методы getMessage(), getCode(), getFile(), getLine(), getTrace(), getTraceAsString(), а так же переопределяемый метод __toString().

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

Bitrix\Main\SystemException базовый класс всех системных исключений, от которого наследуются все остальные исключения. Данный класс переопределяет конструктор системного класса \Exception. Если системный класс на вход принимает сообщение и код ошибки:

<?php
public function __construct($message = null, $code = 0, Exception $previous = null);

, то конструктор Main\SystemException на вход принимает кроме этого файл в котором было выброшено исключение и номер строки:

<?php
public function __construct($message = "", $code = 0, $file = "", $line = 0, \Exception $previous = null);

Выбрасываемое исключение должно иметь максимально подходящий тип.

Если ваш метод создает исключение, то необходимо описать это в phpDoc метода.

В Bitrix Framework это делается таким образом:

 /**
     * Searches connection parameters (type, host, db, login and password) by connection name
     *
     * @param string $name Connection name
     * @return array|null
     * @throws \Bitrix\Main\ArgumentTypeException
     * @throws \Bitrix\Main\ArgumentNullException
     */
    protected function getConnectionParameters($name) {}

Игнорирование исключений

Иногда необходимо чтобы произошедшая ошибка не приводила к прерыванию выполнения скрипта. Пример такой реализации можно рассмотреть в самом продукте в виде работы административной страницы модуля CDN.

Если включён CDN, то вверху страницы отображается информация о расходе трафика. В коде это реализовано так:

$cdn_config = CBitrixCloudCDNConfig::getInstance()->loadFromOptions();
$APPLICATION->SetTitle(GetMessage("BCL_TITLE"));
require($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/include/prolog_admin_after.php");
if (is_object($message))
	echo $message->Show();

if (CBitrixCloudCDN::IsActive())
{
	try
	{
		if ($cdn_config->getQuota()->isExpired())
			$cdn_config->updateQuota();

		$cdn_quota = $cdn_config->getQuota();
		if ($cdn_quota->getAllowedSize() > 0.0 || $cdn_quota->getTrafficSize() > 0.0)
		{
			CAdminMessage::ShowMessage(array(
				"TYPE" => "PROGRESS",
				"DETAILS" => '

'.GetMessage("BCL_CDN_USAGE", array( "#TRAFFIC#" => CFile::FormatSize($cdn_quota->getTrafficSize()), "#ALLOWED#" => CFile::FormatSize($cdn_quota->getAllowedSize()), )).'

#PROGRESS_BAR#', "HTML" => true, "PROGRESS_TOTAL" => $cdn_quota->getAllowedSize(), "PROGRESS_VALUE" => $cdn_quota->getTrafficSize(), )); } } catch (Exception $e) { CAdminMessage::ShowMessage($e->getMessage()); } }

По коду видно, что если CDN активен, то формируется прогресс-бар с выводом информации о расходе трафика. Но если в ходе выполнения этого кода произойдёт ошибка, то будет выброшено исключение. Это исключение будет перехвачено так как весь код находиться в try и сработает ветка, после catch, где выводится сообщение об ошибке штатной функцией. Выполнение скрипта при этом не будет прервано:



37
Курсы разработаны в компании «1С-Битрикс»

Если вы нашли неточность в тексте, непонятное объяснение, пожалуйста, сообщите нам об этом в комментариях.
Развернуть комментарии