src/Internal/RethrowExceptionTrait.php source

1 <?php
2
3 namespace phasync\Internal;
4
5 use Exception;
6
7 trait RethrowExceptionTrait
8 {
9 /**
10 * This function ensures that exceptions appear to be thrown from the
11 * right place even if they are thrown by phasync via the Fiber API.
12 *
13 * @internal
14 *
15 * @throws \ReflectionException
16 */
17 public function rebuildStackTrace(): void
18 {
19 return;
20 // Get the current stack trace
21 $finalTrace = [];
22 $file = null;
23 $line = null;
24 $capturing = false;
25 $baseDir = \dirname(__DIR__, 2);
26 foreach (\debug_backtrace(\DEBUG_BACKTRACE_IGNORE_ARGS) as $trace) {
27 if (!$capturing) {
28 if (!empty($trace['file']) && (\str_starts_with($trace['file'], $baseDir . \DIRECTORY_SEPARATOR . 'src') || $trace['file'] === $baseDir . \DIRECTORY_SEPARATOR . 'phasync.php')) {
29 continue;
30 }
31 if (empty($trace['file'])) {
32 continue;
33 }
34 $capturing = true;
35 $file = $trace['file'];
36 $line = $trace['line'];
37 continue;
38 }
39 $finalTrace[] = $trace;
40 }
41
42 // Get reflection of the current exception
43 $reflection = new \ReflectionClass(\Exception::class);
44
45 // Update the stack trace
46 $traceProperty = $reflection->getProperty('trace');
47 $traceProperty->setAccessible(true);
48 $traceProperty->setValue($this, $finalTrace);
49
50 // Update the file and line where the exception was rethrown
51 $fileProperty = $reflection->getProperty('file');
52 $fileProperty->setAccessible(true);
53 $fileProperty->setValue($this, $file);
54
55 $lineProperty = $reflection->getProperty('line');
56 $lineProperty->setAccessible(true);
57 $lineProperty->setValue($this, $line);
58 }
59 }
60