GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.

BacktraceFactory::offsetForThrownException()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 4
c 1
b 0
f 0
nc 1
nop 1
dl 0
loc 8
rs 10
1
<?php
2
3
namespace Honeybadger;
4
5
use ReflectionClass;
6
use ReflectionException;
7
use Throwable;
8
9
class BacktraceFactory
10
{
11
    /**
12
     * @var \Throwable
13
     */
14
    protected $exception;
15
16
    /**
17
     * @param   \Throwable  $exception
18
     */
19
    public function __construct(Throwable $exception)
20
    {
21
        $this->exception = $exception;
22
    }
23
24
    /**
25
     * @return array
26
     */
27
    public function trace(): array
28
    {
29
        $backtrace = $this->offsetForThrownException(
30
            $this->exception->getTrace()
31
        );
32
33
        return $this->formatBacktrace($backtrace);
34
    }
35
36
    /**
37
     * @return array
38
     */
39
    public function previous(): array
40
    {
41
        return $this->formatPrevious($this->exception);
42
    }
43
44
    /**
45
     * @param  \Throwable  $e
46
     * @param  array  $previousCauses
47
     * @return array
48
     */
49
    private function formatPrevious(Throwable $e, array $previousCauses = []): array
50
    {
51
        if ($e = $e->getPrevious()) {
52
            $previousCauses[] = [
53
                'class' => get_class($e),
54
                'message' => $e->getMessage(),
55
                'backtrace' => (new self($e))->trace(),
56
            ];
57
58
            return $this->formatPrevious($e, $previousCauses);
59
        }
60
61
        return $previousCauses;
62
    }
63
64
    /**
65
     * @param  array  $backtrace
66
     * @return array
67
     */
68
    private function offsetForThrownException(array $backtrace): array
69
    {
70
        $backtrace[0] = array_merge($backtrace[0] ?? [], [
71
            'line' => $this->exception->getLine(),
72
            'file' => $this->exception->getFile(),
73
        ]);
74
75
        return $backtrace;
76
    }
77
78
    /**
79
     * @param  array  $backtrace
80
     * @return array
81
     */
82
    private function formatBacktrace(array $backtrace): array
83
    {
84
        return array_map(function ($frame) {
85
            if (! array_key_exists('file', $frame)) {
86
                $context = $this->contextWithoutFile($frame);
87
            } else {
88
                $context = $this->contextWithFile($frame);
89
            }
90
91
            return array_merge($context, [
92
                'method' => $frame['function'] ?? null,
93
                'args' => $this->parseArgs($frame['args'] ?? []),
94
                'class' => $frame['class'] ?? null,
95
                'type' => $frame['type'] ?? null,
96
            ]);
97
        }, $backtrace);
98
    }
99
100
    /**
101
     * Parse method arguments and make any transformations.
102
     *
103
     * @param array $args
104
     * @return array
105
     */
106
    private function parseArgs(array $args): array
107
    {
108
        return array_map(function ($arg) {
109
            if (is_object($arg)) {
110
                return get_class($arg);
111
            }
112
113
            return $arg;
114
        }, $args);
115
    }
116
117
    /**
118
     * @param  array  $frame
119
     * @return array
120
     */
121
    private function contextWithoutFile(array $frame): array
122
    {
123
        if (! empty($frame['class'])) {
124
            $filename = sprintf('%s%s%s', $frame['class'], $frame['type'], $frame['function']);
125
126
            try {
127
                $reflect = new ReflectionClass($frame['class']);
128
                $filename = $reflect->getFileName();
129
            } catch (ReflectionException $e) {
130
                // Forget it if we run into errors, it's not worth it.
131
            }
132
        } elseif (! empty($frame['function'])) {
133
            $filename = sprintf('%s(anonymous)', $frame['function']);
134
        } else {
135
            $filename = sprintf('(anonymous)');
136
        }
137
138
        if (empty($filename)) {
139
            $filename = '[Anonymous function]';
140
        }
141
142
        return [
143
            'source' => null,
144
            'file' => $filename,
145
            'number' => '0',
146
        ];
147
    }
148
149
    /**
150
     * @param  array  $frame
151
     * @return array
152
     */
153
    private function contextWithFile(array $frame): array
154
    {
155
        return [
156
            'source' => (new FileSource($frame['file'], $frame['line']))->getSource(),
157
            'file' => $frame['file'],
158
            'number' => (string) $frame['line'],
159
        ];
160
    }
161
}
162