diff options
Diffstat (limited to 'lib/private/Support')
-rw-r--r-- | lib/private/Support/CrashReport/Registry.php | 66 |
1 files changed, 65 insertions, 1 deletions
diff --git a/lib/private/Support/CrashReport/Registry.php b/lib/private/Support/CrashReport/Registry.php index 44a6d290678..bff62705ceb 100644 --- a/lib/private/Support/CrashReport/Registry.php +++ b/lib/private/Support/CrashReport/Registry.php @@ -1,4 +1,7 @@ <?php + +declare(strict_types=1); + /** * * @@ -25,6 +28,9 @@ namespace OC\Support\CrashReport; use Exception; +use OCP\AppFramework\QueryException; +use OCP\ILogger; +use OCP\IServerContainer; use OCP\Support\CrashReport\ICollectBreadcrumbs; use OCP\Support\CrashReport\IMessageReporter; use OCP\Support\CrashReport\IRegistry; @@ -33,9 +39,22 @@ use Throwable; class Registry implements IRegistry { + /** @var string[] */ + private $lazyReporters = []; + /** @var IReporter[] */ private $reporters = []; + /** @var IServerContainer */ + private $serverContainer; + + /** @var ILogger */ + private $logger; + + public function __construct(IServerContainer $serverContainer) { + $this->serverContainer = $serverContainer; + } + /** * Register a reporter instance * @@ -45,6 +64,10 @@ class Registry implements IRegistry { $this->reporters[] = $reporter; } + public function registerLazy(string $class): void { + $this->lazyReporters[] = $class; + } + /** * Delegate breadcrumb collection to all registered reporters * @@ -55,6 +78,8 @@ class Registry implements IRegistry { * @since 15.0.0 */ public function delegateBreadcrumb(string $message, string $category, array $context = []): void { + $this->loadLazyProviders(); + foreach ($this->reporters as $reporter) { if ($reporter instanceof ICollectBreadcrumbs) { $reporter->collect($message, $category, $context); @@ -69,7 +94,8 @@ class Registry implements IRegistry { * @param array $context */ public function delegateReport($exception, array $context = []): void { - /** @var IReporter $reporter */ + $this->loadLazyProviders(); + foreach ($this->reporters as $reporter) { $reporter->report($exception, $context); } @@ -84,10 +110,48 @@ class Registry implements IRegistry { * @return void */ public function delegateMessage(string $message, array $context = []): void { + $this->loadLazyProviders(); + foreach ($this->reporters as $reporter) { if ($reporter instanceof IMessageReporter) { $reporter->reportMessage($message, $context); } } } + + private function loadLazyProviders(): void { + $classes = $this->lazyReporters; + foreach ($classes as $class) { + try { + /** @var IReporter $reporter */ + $reporter = $this->serverContainer->query($class); + } catch (QueryException $e) { + /* + * There is a circular dependency between the logger and the registry, so + * we can not inject it. Thus the static call. + */ + \OC::$server->getLogger()->logException($e, [ + 'message' => 'Could not load lazy crash reporter: ' . $e->getMessage(), + 'level' => ILogger::FATAL, + ]); + } + /** + * Try to register the loaded reporter. Theoretically it could be of a wrong + * type, so we might get a TypeError here that we should catch. + */ + try { + $this->register($reporter); + } catch (Throwable $e) { + /* + * There is a circular dependency between the logger and the registry, so + * we can not inject it. Thus the static call. + */ + \OC::$server->getLogger()->logException($e, [ + 'message' => 'Could not register lazy crash reporter: ' . $e->getMessage(), + 'level' => ILogger::FATAL, + ]); + } + } + $this->lazyReporters = []; + } } |