* * Also initializes error reporting, catching and reporting all errors surfacing from the event loop. * * @param string $eventHandler Event handler class name */ protected function startAndLoopInternal(string $eventHandler): void { $started = false; $errors = []; $prev = EventLoop::getErrorHandler(); EventLoop::setErrorHandler( $cb = function (\Throwable $e) use (&$errors, &$started): void { if ($e instanceof UnhandledFutureError) { $e = $e->getPrevious(); } if ($e instanceof SecurityException || $e instanceof SignalException) { throw $e; } if (str_starts_with($e->getMessage(), 'Could not connect to DC ')) { throw $e; } $t = time(); $errors = [$t => $errors[$t] ?? 0]; $errors[$t]++; if ($errors[$t] > 10 && (!$this->wrapper->getAPI()->isInited() || !$started)) { $this->wrapper->logger('More than 10 errors in a second and not inited, exiting!', Logger::FATAL_ERROR); return; } $eOrig = (string) $e; $e = Tools::taintEscape((string) $e); echo $e; $this->wrapper->logger($eOrig, Logger::FATAL_ERROR); $this->report("Surfaced: $eOrig"); } ); try { $this->startAndLoopLogic($eventHandler, $started); } finally { if (EventLoop::getErrorHandler() === $cb) { EventLoop::setErrorHandler($prev); } } } abstract protected function reconnectFull(): bool;