*/ class action_plugin_sentry_ajax extends DokuWiki_Action_Plugin { /** * Registers a callback function for a given event * * @param Doku_Event_Handler $controller DokuWiki's event controller object * * @return void */ public function register(Doku_Event_Handler $controller) { if (!$this->getConf('dsn')) { return; } $controller->register_hook('AJAX_CALL_UNKNOWN', 'BEFORE', $this, 'handleAjax'); } /** * * This uses event AJAX_CALL_UNKNOWN * * @param Doku_Event $event * @param $param */ public function handleAjax(Doku_Event $event, $param) { if ($event->data !== 'plugin_sentry') { return; } $event->preventDefault(); $event->stopPropagation(); global $INPUT; $sentryData = [ 'logger' => 'javascript', 'exception' => [ 'values' => [ [ 'type' => $INPUT->str('name'), 'value' => $INPUT->str('message'), 'stacktrace' => [ 'frames' => $this->parseJavaScriptStacktrace($INPUT->str('stack')) ], ], ], ], ]; $sentryData = array_merge($sentryData, $INPUT->arr('additionalData')); $sentryData['extra']['original_stack'] = $INPUT->str('stack'); $sentryEvent = new \dokuwiki\plugin\sentry\Event($sentryData); /** @var helper_plugin_sentry $sentryHelper */ $sentryHelper = plugin_load('helper', 'sentry'); $sentryHelper->logEvent($sentryEvent); } /** * Tries to parse a JavaScript stack trace into sentry frames * * @see https://github.com/errwischt/stacktrace-parser/blob/master/lib/stacktrace-parser.js * @param string $trace * @return array */ protected function parseJavaScriptStacktrace($trace) { $chrome = '/^\s*at (?:(?:(?:Anonymous function)?|((?:\[object object\])?(?:new )?\S+'. '(?: \[as \S+\])?)) )?\(?((?:[-\w]+):.*?):(\d+)(?::(\d+))?\)?\s*$/i'; $gecko = '/^(?:\s*([^@]*)(?:\((.*?)\))?@)?(\S.*?):(\d+)(?::(\d+))?\s*$/i'; $frames = []; $lines = explode("\n", $trace); foreach ($lines as $line) { if (preg_match($gecko, $line, $parts)) { $frames[] = [ 'filename' => $parts[3] ? $parts[3] : '', 'function' => $parts[1] ? $parts[1] : '', 'lineno' => (int)$parts[4], 'colno' => (int)$parts[5] ]; } elseif (preg_match($chrome, $line, $parts)) { $frames[] = [ 'filename' => $parts[2] ? $parts[2] : '', 'function' => $parts[1] ? $parts[1] : '', 'lineno' => (int)$parts[3], 'colno' => (int)$parts[4] ]; } } return array_reverse($frames); } }