Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
26 / 26
100.00% covered (success)
100.00%
9 / 9
CRAP
100.00% covered (success)
100.00%
1 / 1
Handler
100.00% covered (success)
100.00%
26 / 26
100.00% covered (success)
100.00%
9 / 9
17
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 register
n/a
0 / 0
n/a
0 / 0
3
 errorHandler
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 exceptionHandler
100.00% covered (success)
100.00%
14 / 14
100.00% covered (success)
100.00%
1 / 1
4
 terminateApplicationImmediately
n/a
0 / 0
n/a
0 / 0
1
 getEnvironment
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setEnvironment
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getHandler
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
 setHandler
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getRequest
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setRequest
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3declare(strict_types=1);
4
5namespace Engelsystem\Exceptions;
6
7use Engelsystem\Environment;
8use Engelsystem\Exceptions\Handlers\HandlerInterface;
9use Engelsystem\Exceptions\Handlers\Legacy;
10use Engelsystem\Http\Request;
11use ErrorException;
12use Throwable;
13
14class Handler
15{
16    /** @var HandlerInterface[] */
17    protected array $handler = [];
18
19    protected ?Request $request = null;
20
21    /**
22     * Handler constructor.
23     *
24     * @param Environment $environment prod|dev
25     */
26    public function __construct(protected Environment $environment = Environment::PRODUCTION)
27    {
28    }
29
30    /**
31     * Activate the error handler
32     * @codeCoverageIgnore
33     */
34    public function register(): void
35    {
36        if (defined('PHPUNIT_COMPOSER_INSTALL')) {
37            return;
38        }
39
40        $level = $this->environment == Environment::DEVELOPMENT
41            ? E_ALL
42            : E_RECOVERABLE_ERROR | E_COMPILE_ERROR;
43        set_error_handler([$this, 'errorHandler'], $level);
44        set_exception_handler([$this, 'exceptionHandler']);
45    }
46
47    public function errorHandler(int $number, string $message, string $file, int $line): void
48    {
49        $exception = new ErrorException($message, 0, $number, $file, $line);
50        $this->exceptionHandler($exception);
51    }
52
53    public function exceptionHandler(Throwable $e, bool $return = false): string
54    {
55        if (!$this->request instanceof Request) {
56            $this->request = new Request();
57        }
58
59        $handler = $this->handler[$this->environment->value] ?? new Legacy();
60        $handler->report($e);
61        ob_start();
62        $handler->render($this->request, $e);
63
64        if ($return) {
65            $output = ob_get_contents();
66            ob_end_clean();
67            return $output;
68        }
69
70        if (!headers_sent()) {
71            // @codeCoverageIgnoreStart
72            http_response_code(500);
73            // @codeCoverageIgnoreEnd
74        }
75
76        ob_end_flush();
77
78        $this->terminateApplicationImmediately();
79
80        return '';
81    }
82
83    /**
84     * Exit the application
85     *
86     * @codeCoverageIgnore
87     */
88    protected function terminateApplicationImmediately(string $message = ''): void
89    {
90        echo $message;
91        die(1);
92    }
93
94    public function getEnvironment(): Environment
95    {
96        return $this->environment;
97    }
98
99    public function setEnvironment(Environment $environment): void
100    {
101        $this->environment = $environment;
102    }
103
104    /**
105     * @return HandlerInterface|HandlerInterface[]
106     */
107    public function getHandler(?Environment $environment = null): HandlerInterface|array
108    {
109        if (!is_null($environment)) {
110            return $this->handler[$environment->value];
111        }
112
113        return $this->handler;
114    }
115
116    public function setHandler(Environment $environment, HandlerInterface $handler): void
117    {
118        $this->handler[$environment->value] = $handler;
119    }
120
121    public function getRequest(): Request
122    {
123        return $this->request;
124    }
125
126    public function setRequest(Request $request): void
127    {
128        $this->request = $request;
129    }
130}