Бизнес-процессы
Журнал, отладка и ошибки
Как писать сообщения в журнал бизнес-процесса, отлаживать PHP-код, ловить ошибки и разбирать зависшие процессы.
Если в PHP-блоке ошибка, процесс может остановиться без понятного сообщения в интерфейсе.
Поэтому рабочий минимум — писать ключевые шаги в журнал процесса и оборачивать PHP-код в
try-catch.
Журнал процесса
Журнал бизнес-процесса помогает понять, какие данные были внутри конкретного запуска.
WriteToTrackingService
Для записи в отчёт используется WriteToTrackingService(). Первый параметр
должен быть строкой.
$this->WriteToTrackingService(
'PHP-блок начал выполнение',
0,
\CBPTrackingType::Report
); | Тип | Когда использовать |
|---|---|
\CBPTrackingType::Report | Обычные сообщения для отчёта. |
\CBPTrackingType::Error | Ошибка, которую нужно явно показать. |
\CBPTrackingType::FaultActivity | Критическая ошибка действия. |
\CBPTrackingType::Custom | Пользовательское сообщение. |
Массивы и JSON
Массив нужно сначала преобразовать в строку: через print_r() или
json_encode().
/**
* Пишет массив в журнал процесса.
*/
function writeArrayToTracking($context, array $items): void
{
$context->WriteToTrackingService(
print_r($items, true),
0,
\CBPTrackingType::Report
);
}
/**
* Пишет массив в журнал процесса как JSON.
*/
function writeJsonToTracking($context, array $items): void
{
$context->WriteToTrackingService(
json_encode($items, JSON_UNESCAPED_UNICODE),
0,
\CBPTrackingType::Report
);
}
writeArrayToTracking($this, ['deal_id' => 123]);
writeJsonToTracking($this, ['deal_id' => 123]); Отладка
Для PHP-кода в бизнес-процессе лучше сразу закладывать обработку ошибок.
try-catch
/**
* Пишет ошибку в журнал бизнес-процесса.
*/
function writeBpException($context, \Throwable $exception): void
{
$message = sprintf(
'Ошибка: %s. Файл: %s. Строка: %s',
$exception->getMessage(),
$exception->getFile(),
$exception->getLine()
);
$context->WriteToTrackingService(
$message,
0,
\CBPTrackingType::FaultActivity
);
}
try {
$this->WriteToTrackingService(
'Начало PHP-блока',
0,
\CBPTrackingType::Report
);
// Основной код
$this->WriteToTrackingService(
'Конец PHP-блока',
0,
\CBPTrackingType::Report
);
} catch (\Throwable $exception) {
writeBpException($this, $exception);
// Если процесс должен остановиться, можно пробросить ошибку дальше.
// throw $exception;
} Лог в файл Битрикса
Для технической отладки можно писать в обычный лог Битрикса через
AddMessage2Log(). Это не заменяет журнал процесса, но помогает при
проверке серверного кода.
/**
* Пишет сообщение в лог Битрикса.
*/
function writeBitrixLog(string $message, array $context = []): void
{
AddMessage2Log(
[
'message' => $message,
'context' => $context,
],
'bizproc_debug'
);
}
writeBitrixLog(
'Проверка PHP-блока бизнес-процесса',
[
'document_id' => $this->getDocumentId(),
]
); Ошибки и зависшие процессы
Если процесс не идёт дальше, нужно понять: он упал с ошибкой, ждёт задание, ждёт паузу, ждёт внешнее событие или завис из-за кода.
Что смотреть первым
- журнал бизнес-процесса;
- ошибки PHP в логах сервера;
- Network в браузере, если процесс стартует от действия в интерфейсе;
- задания бизнес-процесса, если процесс ждёт пользователя;
- паузы, ожидания дат и ожидания внешних событий;
- код пользовательских действий, если они есть в шаблоне.
Найти запущенные процессы
Для технической диагностики можно посмотреть экземпляры бизнес-процессов в таблице экземпляров workflow.
\Bitrix\Main\Loader::includeModule('bizproc');
/**
* Получает последние запущенные экземпляры бизнес-процессов.
*/
function fetchRecentWorkflowInstances(int $limit): array
{
$workflows = [];
$workflow_result = \Bitrix\Bizproc\Workflow\Entity\WorkflowInstanceTable::getList([
'select' => [
'ID',
'WORKFLOW_TEMPLATE_ID',
'DOCUMENT_ID',
'STARTED',
'STARTED_BY',
'MODIFIED',
'OWNER_ID',
],
'order' => [
'MODIFIED' => 'DESC',
],
'limit' => $limit,
]);
while ($workflow = $workflow_result->fetch()) {
$workflows[] = $workflow;
}
return $workflows;
}
$workflows = fetchRecentWorkflowInstances(20);
print_r($workflows); Остановить процесс
Если нужно аварийно остановить процесс, можно использовать
CBPDocument::TerminateWorkflow(). Перед этим лучше сохранить ID процесса и
document id в лог.
\Bitrix\Main\Loader::includeModule('bizproc');
/**
* Останавливает бизнес-процесс.
*/
function terminateWorkflow(string $workflow_id, array $document_id): array
{
$error_messages = [];
\CBPDocument::TerminateWorkflow(
$workflow_id,
$document_id,
$error_messages
);
return [
'is_success' => empty($error_messages),
'error_messages' => $error_messages,
];
}
$terminate_result = terminateWorkflow(
$workflow_id,
[
'crm',
'CCrmDocumentDeal',
'DEAL_' . $deal_id,
]
);
print_r($terminate_result);