/** * @param int $levelsToSkip * Позволяет при записи стека вызовов пропустить несколько последних вызовов функций, * которые и так очевидны (например, вызов данной функции, вызов df_bt() и т.п.) * @return void */ function df_bt($levelsToSkip = 0) { /** @var array $bt */ $bt = array_slice(debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS), $levelsToSkip); /** @var array $compactBT */ $compactBT = []; /** @var int $traceLength */ $traceLength = count($bt); /** * 2015-07-23 * 1) Удаляем часть файлового пути до корневой папки Magento. * 2) Заменяем разделитель папок на унифицированный. */ /** @var string $bp */ $bp = BP . DS; /** @var bool $nonStandardDS */ $nonStandardDS = DS !== '/'; for ($traceIndex = 0; $traceIndex < $traceLength; $traceIndex++) { /** @var array $currentState */ $currentState = dfa($bt, $traceIndex); /** @var array(string => string) $nextState */ $nextState = dfa($bt, 1 + $traceIndex, []); /** @var string $file */ $file = str_replace($bp, '', dfa($currentState, 'file')); if ($nonStandardDS) { $file = df_path_n($file); } $compactBT[] = ['File' => $file, 'Line' => dfa($currentState, 'line'), 'Caller' => !$nextState ? '' : df_cc_method($nextState), 'Callee' => !$currentState ? '' : df_cc_method($currentState)]; } df_report('bt-{date}-{time}.log', print_r($compactBT, true)); }
/** * @used-by df_notify_exception() * @used-by \Df\Qa\Message_Failure_Error::check() * @return void * @throws \Exception */ public final function log() { /** * 2015-04-04 * Нам нужно правильно обработать ситуацию, * когда при формировании диагностического отчёта о сбое происходит новый сбой. * 1) Статическая переменная $inProcess предотвращает нас от бесконечной рекурсии. * 2) try... catch позволяет нам перехватить внутренний сбой, * сформировать диагностическое сообщение о нём, * а затем перевозбудить его снова, чтобы вывести на экран. * Обратите внимание, что внутренний сбой не будет виден на экране при асинхронном запросе * (много таких запросов делает, например, страница оформления заказа), * поэтому try... catch с целью записи отчёта крайне важно: * без этого при сбое асинхроноого запроса диагностичекское сообщение о сбое * окажется утраченным. */ static $inProcess; if (!$inProcess) { $inProcess = true; try { df_report($this->reportName(), $this->report()); $inProcess = false; } catch (\Exception $e) { df_log(df_ets($e)); throw $e; } } }
/** * @throws \Exception * @return void */ private function throwNotMatch() { /** @var string $message */ if (!$this->isSubjectMultiline()) { $message = "Строка «{$this->getSubject()}»" . " не отвечает регулярному выражению «{$this->getPattern()}»."; } else { if (!$this->isSubjectTooLongToReport()) { $message = "Указанный ниже текст не отвечает регулярному выражению «{$this->getPattern()}»:" . "\nНАЧАЛО ТЕКСТА:\n{$this->getSubject()}\nКОНЕЦ ТЕКСТА"; } else { df_report($this->getReportFileName(), $this->getSubject()); $message = "Текст не отвечает регулярному выражению «{$this->getPattern()}»." . "\nТекст смотрите в файле {$this->getReportFilePath()}." . "\nПервые {$this->getSubjectMaxLinesToReport()} строк текста:" . "\nНАЧАЛО:\n{$this->getSubjectReportPart()}\nКОНЕЦ"; } } df_error($message); }
/** * 2016-09-08 * @param string|object $caller * @param string|mixed[] $data * @param string|null $suffix [optional] * @return void */ function dfp_report($caller, $data, $suffix = null) { df_report(df_ccc('--', 'mage2.pro/' . dfp_method_code($caller) . '-{date}--{time}', $suffix) . '.log', !is_array($data) ? $data : df_json_encode_pretty($data)); }