|
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
|
|