Lines 91.66% 11 / 12
Functions and Methods 75.00% 3 / 4
Classes and Traits 0.00% 0 / 1
Name Lines Functions and Methods CRAP Classes and Traits
LoopErrorLogger 91.66% 11 / 12 75.00% 3 / 4 6.02 0.00% 0 / 1
 __construct 100.00% 1 / 1 100.00% 1 / 1 1
 install 100.00% 5 / 5 100.00% 1 / 1 2
 restorePrevious 80.00% 4 / 5 0.00% 0 / 1 2.03
 logError 100.00% 1 / 1 100.00% 1 / 1 1
1<?php
2
3declare(strict_types=1);
4
5namespace Stewart\Runtime\Broker;
6
7use Closure;
8use Psr\Log\LoggerInterface;
9use Revolt\EventLoop;
10use Throwable;
11
12final class LoopErrorLogger
13{
14    /** @var (Closure(Throwable): void)|null */
15    private ?Closure $previous = null;
16
17    private bool $installed = false;
18
19    public function __construct(private readonly LoggerInterface $logger) {}
20
21    public function install(): void
22    {
23        if ($this->installed) {
24            return;
25        }
26
27        $this->previous = EventLoop::getErrorHandler();
28        EventLoop::setErrorHandler($this->logError(...));
29        $this->installed = true;
30    }
31
32    public function restorePrevious(): void
33    {
34        if (!$this->installed) {
35            return;
36        }
37
38        EventLoop::setErrorHandler($this->previous);
39        $this->previous = null;
40        $this->installed = false;
41    }
42
43    private function logError(Throwable $error): void
44    {
45        $this->logger->critical('Unhandled error in the event loop', ['exception' => $error]);
46    }
47}