Skip to content

Commit c162cb6

Browse files
committed
Refactor code for better readability
1 parent c6a9047 commit c162cb6

File tree

2 files changed

+127
-77
lines changed

2 files changed

+127
-77
lines changed

src/Debug.php

Lines changed: 126 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@
33
namespace Squirrel\Debug;
44

55
/**
6-
* Debug functionality: create exception, sanitize data
6+
* Debug functionality: create exceptions, sanitize data and function arguments
77
*/
8-
class Debug
8+
final class Debug
99
{
1010
/**
1111
* Create exception with correct backtrace while ignoring some classes/interfaces ($ignoreClasses)
@@ -21,24 +21,11 @@ public static function createException(
2121
string|array $ignoreNamespaces = [],
2222
?\Throwable $previousException = null,
2323
): \Throwable {
24-
if (\is_string($ignoreClasses)) {
25-
$ignoreClasses = [$ignoreClasses];
26-
}
27-
28-
if (\is_string($ignoreNamespaces)) {
29-
$ignoreNamespaces = [$ignoreNamespaces];
30-
}
31-
32-
$removeEmptyStrings = function (string $s): bool {
33-
if (\strlen($s) === 0) {
34-
return false;
35-
}
36-
37-
return true;
38-
};
24+
$ignoreClasses = self::convertToArray($ignoreClasses);
25+
$ignoreNamespaces = self::convertToArray($ignoreNamespaces);
3926

40-
$ignoreClasses = \array_filter($ignoreClasses, $removeEmptyStrings);
41-
$ignoreNamespaces = \array_filter($ignoreNamespaces, $removeEmptyStrings);
27+
$ignoreClasses = \array_filter($ignoreClasses, [Debug::class, 'isNotEmptyString']);
28+
$ignoreNamespaces = \array_filter($ignoreNamespaces, [Debug::class, 'isNotEmptyString']);
4229

4330
// Get backtrace to find out where the query error originated
4431
$backtraceList = \debug_backtrace(DEBUG_BACKTRACE_PROVIDE_OBJECT);
@@ -56,42 +43,14 @@ public static function createException(
5643

5744
$lastInstance ??= $backtrace;
5845

59-
$classImplements = \class_implements($backtrace['class']);
60-
$classParents = \class_parents($backtrace['class']);
61-
62-
// @codeCoverageIgnoreStart
63-
if ($classImplements === false) {
64-
$classImplements = [];
65-
}
66-
67-
if ($classParents === false) {
68-
$classParents = [];
69-
}
70-
// @codeCoverageIgnoreEnd
71-
72-
foreach ($ignoreClasses as $ignoreClass) {
73-
// Check if the class or interface we are looking for is implemented or used
74-
// by the current backtrace class
75-
if (
76-
\in_array($ignoreClass, $classImplements, true) ||
77-
\in_array($ignoreClass, $classParents, true) ||
78-
$ignoreClass === $backtrace['class']
79-
) {
80-
$lastInstance = $backtrace;
81-
82-
continue 2;
83-
}
46+
if (self::isIgnoredClass($backtrace['class'], $ignoreClasses)) {
47+
$lastInstance = $backtrace;
48+
continue;
8449
}
8550

86-
foreach ($ignoreNamespaces as $ignoreNamespace) {
87-
// Check if the backtrace class starts with any ignored namespaces
88-
if (
89-
\str_starts_with($backtrace['class'], $ignoreNamespace)
90-
) {
91-
$lastInstance = $backtrace;
92-
93-
continue 2;
94-
}
51+
if (self::isIgnoredNamespace($backtrace['class'], $ignoreNamespaces)) {
52+
$lastInstance = $backtrace;
53+
continue;
9554
}
9655

9756
// We reached the first non-ignored backtrace - we are at the top
@@ -106,26 +65,16 @@ public static function createException(
10665
$parts = \explode('\\', $lastInstance['class'] ?? '');
10766
$shownClass = \array_pop($parts);
10867

109-
$classImplements = \class_implements($exceptionClass);
110-
$classParents = \class_parents($exceptionClass);
111-
112-
// @codeCoverageIgnoreStart
113-
if ($classImplements === false) {
114-
$classImplements = [];
115-
}
116-
117-
if ($classParents === false) {
118-
$classParents = [];
119-
}
120-
// @codeCoverageIgnoreEnd
121-
122-
// Make sure the provided exception class inherits from Throwable, otherwise replace it with Exception
123-
if (!\in_array(\Throwable::class, $classImplements, true)) {
68+
// Make sure the provided exception class inherits from Throwable or replace it with Exception
69+
if (!\in_array(\Throwable::class, self::getClassInterfaces($exceptionClass), true)) {
12470
$exceptionClass = \Exception::class;
12571
}
12672

12773
// If we have no OriginException child class, we assume the default Exception class constructor is used
128-
if (!\in_array(OriginException::class, $classParents, true) && $exceptionClass !== OriginException::class) {
74+
if (
75+
!\in_array(OriginException::class, self::getClassParents($exceptionClass), true)
76+
&& $exceptionClass !== OriginException::class
77+
) {
12978
/**
13079
* @var \Throwable $exception At this point we know that $exceptionClass inherits from \Throwable for sure
13180
*/
@@ -139,13 +88,12 @@ public static function createException(
13988
* @var OriginException $exception At this point we know that $exceptionClass inherits from OriginException for sure
14089
*/
14190
$exception = new $exceptionClass(
142-
$shownClass . ($lastInstance['type'] ?? '') . ($lastInstance['function'] ?? '') .
143-
'(' . self::sanitizeArguments($lastInstance['args'] ?? []) . ')',
144-
$lastInstance['file'] ?? '',
145-
$lastInstance['line'] ?? 0,
146-
\str_replace("\n", ' ', $message),
147-
(isset($previousException) ? $previousException->getCode() : 0),
148-
$previousException,
91+
originCall: $shownClass . ($lastInstance['type'] ?? '') . ($lastInstance['function'] ?? '') . '(' . self::sanitizeArguments($lastInstance['args'] ?? []) . ')',
92+
originFile: $lastInstance['file'] ?? '',
93+
originLine: $lastInstance['line'] ?? 0,
94+
message: \str_replace("\n", ' ', $message),
95+
code: (isset($previousException) ? $previousException->getCode() : 0),
96+
previous: $previousException,
14997
);
15098
}
15199

@@ -207,4 +155,106 @@ public static function sanitizeData(mixed $data): string
207155

208156
return '[' . \implode(', ', $result) . ']';
209157
}
158+
159+
private static function convertToArray(string|array $list): array
160+
{
161+
if (\is_string($list)) {
162+
$list = [$list];
163+
}
164+
165+
return $list;
166+
}
167+
168+
private static function isNotEmptyString(string $s): bool
169+
{
170+
if (\strlen($s) === 0) {
171+
return false;
172+
}
173+
174+
return true;
175+
}
176+
177+
/**
178+
* @param class-string $class
179+
* @return array<string, class-string>
180+
*/
181+
private static function getClassParents(string $class): array
182+
{
183+
$classParents = \class_parents($class);
184+
185+
// @codeCoverageIgnoreStart
186+
if ($classParents === false) {
187+
$classParents = [];
188+
}
189+
// @codeCoverageIgnoreEnd
190+
191+
return $classParents;
192+
}
193+
194+
/**
195+
* @param class-string $class
196+
* @return array<string, string>
197+
*/
198+
private static function getClassInterfaces(string $class): array
199+
{
200+
$classImplements = \class_implements($class);
201+
202+
// @codeCoverageIgnoreStart
203+
if ($classImplements === false) {
204+
$classImplements = [];
205+
}
206+
// @codeCoverageIgnoreEnd
207+
208+
return $classImplements;
209+
}
210+
211+
/**
212+
* @param class-string $class
213+
* @return array<string, string>
214+
*/
215+
private static function getClasses(string $class): array
216+
{
217+
return \array_merge(self::getClassInterfaces($class), self::getClassParents($class));
218+
}
219+
220+
/**
221+
* @param class-string $backtraceClass
222+
* @param class-string[] $ignoreClasses
223+
*/
224+
private static function isIgnoredClass(
225+
string $backtraceClass,
226+
array $ignoreClasses,
227+
): bool {
228+
$possibleClasses = self::getClasses($backtraceClass);
229+
230+
foreach ($ignoreClasses as $ignoreClass) {
231+
if (
232+
\in_array($ignoreClass, $possibleClasses, true) ||
233+
$ignoreClass === $backtraceClass
234+
) {
235+
return true;
236+
}
237+
}
238+
239+
return false;
240+
}
241+
242+
/**
243+
* @param class-string $backtraceClass
244+
* @param string[] $ignoreNamespaces
245+
*/
246+
private static function isIgnoredNamespace(
247+
string $backtraceClass,
248+
array $ignoreNamespaces,
249+
): bool {
250+
foreach ($ignoreNamespaces as $ignoreNamespace) {
251+
if (
252+
\str_starts_with($backtraceClass, $ignoreNamespace)
253+
) {
254+
return true;
255+
}
256+
}
257+
258+
return false;
259+
}
210260
}

tests/DebugTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
class DebugTest extends \PHPUnit\Framework\TestCase
1212
{
13-
private const DEBUG_CLASS_EXCEPTION_LINE = 141;
13+
private const DEBUG_CLASS_EXCEPTION_LINE = 90;
1414

1515
public function testCreateException()
1616
{

0 commit comments

Comments
 (0)