Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
100.00% |
54 / 54 |
|
100.00% |
8 / 8 |
CRAP | |
100.00% |
1 / 1 |
ExceptionHandler | |
100.00% |
54 / 54 |
|
100.00% |
8 / 8 |
22 | |
100.00% |
1 / 1 |
__construct | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
1 | |||
addException | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
1 | |||
hasExceptions | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getExceptions | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
prepare | |
100.00% |
13 / 13 |
|
100.00% |
1 / 1 |
3 | |||
prepareHeaderAsString | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
2 | |||
prepareAsString | |
100.00% |
14 / 14 |
|
100.00% |
1 / 1 |
3 | |||
log | |
100.00% |
18 / 18 |
|
100.00% |
1 / 1 |
10 |
1 | <?php |
2 | /** |
3 | * Pop PHP Framework (http://www.popphp.org/) |
4 | * |
5 | * @link https://github.com/popphp/popphp-framework |
6 | * @author Nick Sagona, III <dev@nolainteractive.com> |
7 | * @copyright Copyright (c) 2009-2024 NOLA Interactive, LLC. (http://www.nolainteractive.com) |
8 | * @license http://www.popphp.org/license New BSD License |
9 | */ |
10 | |
11 | /** |
12 | * @namespace |
13 | */ |
14 | namespace Pop\Debug\Handler; |
15 | |
16 | use Pop\Log\Logger; |
17 | |
18 | /** |
19 | * Debug exception handler class |
20 | * |
21 | * @category Pop |
22 | * @package Pop\Debug |
23 | * @author Nick Sagona, III <dev@nolainteractive.com> |
24 | * @copyright Copyright (c) 2009-2024 NOLA Interactive, LLC. (http://www.nolainteractive.com) |
25 | * @license http://www.popphp.org/license New BSD License |
26 | * @version 2.2.0 |
27 | */ |
28 | class ExceptionHandler extends AbstractHandler |
29 | { |
30 | |
31 | /** |
32 | * Verbose flag |
33 | * @var bool |
34 | */ |
35 | protected bool $verbose = false; |
36 | |
37 | /** |
38 | * Exceptions |
39 | * @var array |
40 | */ |
41 | protected array $exceptions = []; |
42 | |
43 | /** |
44 | * Constructor |
45 | * |
46 | * Instantiate a handler object |
47 | * |
48 | * @param bool $verbose |
49 | * @param ?string $name |
50 | * @param ?Logger $logger |
51 | * @param array $loggingParams |
52 | */ |
53 | public function __construct(bool $verbose = false, ?string $name = null, ?Logger $logger = null, array $loggingParams = []) |
54 | { |
55 | parent::__construct($name, $logger, $loggingParams); |
56 | $this->verbose = $verbose; |
57 | } |
58 | |
59 | /** |
60 | * Add exception |
61 | * |
62 | * @param \Exception $exception |
63 | * @return ExceptionHandler |
64 | */ |
65 | public function addException(\Exception $exception): ExceptionHandler |
66 | { |
67 | $this->exceptions[] = ['exception' => $exception, 'timestamp' => (string)microtime(true)]; |
68 | return $this; |
69 | } |
70 | |
71 | /** |
72 | * Determine if the handler has exceptions |
73 | * |
74 | * @return bool |
75 | */ |
76 | public function hasExceptions(): bool |
77 | { |
78 | return (count($this->exceptions) > 0); |
79 | } |
80 | |
81 | /** |
82 | * Get exceptions |
83 | * |
84 | * @return array |
85 | */ |
86 | public function getExceptions(): array |
87 | { |
88 | return $this->exceptions; |
89 | } |
90 | |
91 | /** |
92 | * Prepare handler data for storage |
93 | * |
94 | * @param bool $simpleData |
95 | * @return array |
96 | */ |
97 | public function prepare(bool $simpleData = false): array |
98 | { |
99 | if ($simpleData) { |
100 | $exceptions = []; |
101 | foreach ($this->exceptions as $exception) { |
102 | $exceptions[] = [ |
103 | 'class' => get_class($exception['exception']), |
104 | 'code' => $exception['exception']->getCode(), |
105 | 'line' => $exception['exception']->getLine(), |
106 | 'file' => $exception['exception']->getFile(), |
107 | 'message' => $exception['exception']->getMessage(), |
108 | 'trace' => $exception['exception']->getTrace() |
109 | ]; |
110 | } |
111 | return $exceptions; |
112 | } else { |
113 | return $this->exceptions; |
114 | } |
115 | } |
116 | |
117 | /** |
118 | * Prepare header string |
119 | * |
120 | * @return string |
121 | */ |
122 | public function prepareHeaderAsString(): string |
123 | { |
124 | $string = ((!empty($this->name)) ? $this->name . ' ' : '') . 'Exception Handler'; |
125 | $string .= PHP_EOL . str_repeat('=', strlen($string)) . PHP_EOL; |
126 | |
127 | return $string; |
128 | } |
129 | |
130 | /** |
131 | * Prepare handler data as string |
132 | * |
133 | * @return string |
134 | */ |
135 | public function prepareAsString(): string |
136 | { |
137 | $string = ''; |
138 | |
139 | foreach ($this->exceptions as $exception) { |
140 | if ($this->verbose) { |
141 | $string .= number_format($exception['timestamp'], 5, '.', '') . PHP_EOL . |
142 | "Class: " . get_class($exception['exception']) . PHP_EOL . |
143 | "Code: " . $exception['exception']->getCode() . PHP_EOL . |
144 | "Line: " . $exception['exception']->getLine() . PHP_EOL . |
145 | "File: " . $exception['exception']->getFile() . PHP_EOL . |
146 | "Message: " . $exception['exception']->getMessage() . PHP_EOL . |
147 | "Trace: " . $exception['exception']->getTraceAsString() . PHP_EOL; |
148 | } else { |
149 | $string .= number_format($exception['timestamp'], 5, '.', '') . "\t" . get_class($exception['exception']) . |
150 | "\t" . $exception['exception']->getMessage() . PHP_EOL; |
151 | } |
152 | |
153 | } |
154 | $string .= PHP_EOL; |
155 | |
156 | return $string; |
157 | } |
158 | |
159 | /** |
160 | * Trigger handler logging |
161 | * |
162 | * @throws Exception |
163 | * @return void |
164 | */ |
165 | public function log(): void |
166 | { |
167 | if (($this->hasLogger()) && ($this->hasLoggingParams())) { |
168 | $logLevel = $this->loggingParams['level'] ?? null; |
169 | $useContext = $this->loggingParams['context'] ?? null; |
170 | |
171 | if ($logLevel !== null) { |
172 | $context = []; |
173 | $exceptionClasses = []; |
174 | foreach ($this->exceptions as $exception) { |
175 | $exceptionClasses[] = get_class($exception['exception']); |
176 | } |
177 | |
178 | $message = (count($exceptionClasses) > 1) ? |
179 | 'The following (' . count($exceptionClasses) . ') exceptions have been thrown: ' . implode(', ', $exceptionClasses) : |
180 | 'The following (1) exception has been thrown: ' . implode(', ', $exceptionClasses); |
181 | |
182 | if (!empty($useContext)) { |
183 | $context['exceptions'] = (($useContext !== null) && (strtolower($useContext) == 'text')) ? |
184 | $this->prepareAsString() : $this->prepare(true); |
185 | |
186 | if (is_string($useContext)) { |
187 | $context['format'] = $useContext; |
188 | } |
189 | } |
190 | |
191 | $this->logger->log($logLevel, $message, $context); |
192 | } else { |
193 | throw new Exception('Error: The log level parameter was not set.'); |
194 | } |
195 | } |
196 | } |
197 | |
198 | } |