FaultMutator::mutate()   B
last analyzed

Complexity

Conditions 7
Paths 6

Size

Total Lines 49
Code Lines 23

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 23
c 1
b 0
f 0
dl 0
loc 49
rs 8.6186
cc 7
nc 6
nop 1
1
<?php
2
3
declare(strict_types=1);
4
5
/**
6
 * Author: panosru
7
 * Date: 27/04/2018
8
 * Time: 21:23
9
 */
10
11
namespace Omega\FaultManager\Traits;
12
13
/**
14
 * Trait FaultMutator
15
 * @package Omega\FaultManager\Traits
16
 * @codeCoverageIgnore
17
 */
18
trait FaultMutator
19
{
20
    /**
21
     * @param \Throwable $exception
22
     *
23
     * @throws \ReflectionException
24
     */
25
    protected static function mutate(\Throwable $exception): void
26
    {
27
        // Get exception reflection
28
        $reflection = new \ReflectionObject($exception);
29
30
        // When running PHPUnit property "trace" is not available, works fine though in real world...
31
        // Maybe an xdebug issue?
32
33
        // Get trace
34
        if ($reflection->hasProperty('trace')) {
35
            $trace = $reflection->getProperty('trace');
36
        } else {
37
            $parentClass = $reflection->getParentClass();
38
            // Get parent class \Exception
39
            while (\Exception::class !== $parentClass->getName()) {
40
                $parentClass = $parentClass->getParentClass();
41
            }
42
            $trace = $parentClass->getProperty('trace');
43
        }
44
45
        // Get trace
46
        $trace->setAccessible(true);
47
48
        // Get stack trace
49
        $stackTrace = $trace->getValue($exception);
50
        // Some times $stackTrace may be empty, especially when we call custom generated exceptions with
51
        // traditional way like throw new \MyCustomGeneratedException()
52
        if (0 < \count($stackTrace)) {
53
            // Remove first in stack because it refers to ReflectionClass::newInstanceArgs() we called previously
54
            \array_shift($stackTrace);
55
            // Remove 'Fault::throw()' from trace if present
56
            if (0 === \strcmp('exception', $stackTrace[0]['function']) &&
57
                (
58
                    isset($stackTrace[1]) &&
59
                    0 === \strcmp('throw', $stackTrace[1]['function'])
60
                )
61
            ) {
62
                \array_shift($stackTrace);
63
            }
64
            $trace->setValue($exception, $stackTrace);
65
66
            // Set "file" and "line" properties
67
            $file = $reflection->getProperty('file');
68
            $file->setAccessible(true);
69
            $file->setValue($exception, $stackTrace[0]['file']);
70
71
            $line = $reflection->getProperty('line');
72
            $line->setAccessible(true);
73
            $line->setValue($exception, $stackTrace[0]['line']);
74
        }
75
    }
76
}
77