AddExceptionPropertiesTransformer   A
last analyzed

Complexity

Total Complexity 9

Size/Duplication

Total Lines 76
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 23
c 1
b 0
f 0
dl 0
loc 76
ccs 29
cts 29
cp 1
rs 10
wmc 9

2 Methods

Rating   Name   Duplication   Size   Complexity  
A getPropertyValues() 0 35 6
A transform() 0 16 3
1
<?php
2
3
namespace ShiftOneLabs\PhpRollbarExtensions\Transformers;
4
5
use Error;
6
use Exception;
7
use Throwable;
8
use ReflectionClass;
9
use Rollbar\Payload\Payload;
10
use Rollbar\TransformerInterface;
11
12
class AddExceptionPropertiesTransformer implements TransformerInterface
13
{
14
    /**
15
     * Transform the payload.
16
     *
17
     * This transformer modifies the payload to add all the values of all
18
     * the properties of all the exceptions in the exception chain to
19
     * a properties key on the data custom element.
20
     *
21
     * @param  \Rollbar\Payload\Payload  $payload
22
     * @param  \Rollbar\Payload\Level  $level
23
     * @param  \Exception|\Throwable  $toLog
24
     * @param  $context
25
     *
26
     * @return \Rollbar\Payload\Payload
27
     */
28 95
    public function transform(Payload $payload, $level, $toLog, $context)
29
    {
30
        // The interface docblock only specifies Exceptions and Throwables, but
31
        // $toLog can also be a string. Make sure we only work on Throwables.
32
        // Also check for Exception to support PHP < 7.
33 95
        if (!$toLog instanceof Throwable && !$toLog instanceof Exception) {
0 ignored issues
show
introduced by
$toLog is always a sub-type of Throwable.
Loading history...
34 14
            return $payload;
35
        }
36
37 81
        $custom = $payload->getData()->getCustom();
38
39 81
        $custom['properties'] = json_decode(json_encode($this->getPropertyValues($toLog), JSON_PARTIAL_OUTPUT_ON_ERROR), true);
40
41 81
        $payload->getData()->setCustom($custom);
42
43 81
        return $payload;
44
    }
45
46
    /**
47
     * Recursively get the property values for the exception chain.
48
     *
49
     * @param  \Exception|\Throwable  $exception
50
     *
51
     * @return array
52
     */
53 81
    protected function getPropertyValues($exception)
54
    {
55
        // Get all the values of all the object's properties. Use reflection
56
        // to access all the defined properties, and use get_object_vars
57
        // to access all the dynamically added properties.
58 81
        $properties = array_merge(
59 69
            array_reduce(
60 81
                (new ReflectionClass($exception))->getProperties(),
61 81
                function ($carry, $property) use ($exception) {
62
                    // Exclude some unneeded private properties from the base
63
                    // Exception and Error classes.
64 81
                    if ($property->isPrivate()
65 81
                        && in_array(get_class($exception), [Exception::class, Error::class])
66 81
                        && in_array($property->getName(), ['string', 'trace', 'previous'])) {
67 67
                        return $carry;
68
                    }
69
70 81
                    $property->setAccessible(true);
71
72 81
                    $carry[$property->getName()] = $property->getValue($exception);
73
74 81
                    return $carry;
75 81
                },
76 15
                []
77 15
            ),
78 15
            get_object_vars($exception)
79 15
        );
80
81
        // Go down the exception chain to get all the nested exception values.
82 15
        $previous = $exception->getPrevious();
83 15
        if ($previous instanceof Throwable || $previous instanceof Exception) {
0 ignored issues
show
introduced by
$previous is always a sub-type of Throwable.
Loading history...
84 3
            $properties['previous'] = [get_class($previous) => $this->getPropertyValues($previous)];
85 3
        }
86
87 15
        return $properties;
88
    }
89
}
90