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.
Completed
Pull Request — master (#1)
by Šimon
04:15
created

Error::toSerializableArray()   B

Complexity

Conditions 4
Paths 8

Size

Total Lines 25
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 20

Importance

Changes 0
Metric Value
dl 0
loc 25
ccs 0
cts 0
cp 0
rs 8.5806
c 0
b 0
f 0
cc 4
eloc 13
nc 8
nop 0
crap 20
1
<?php
2
3
declare(strict_types=1);
4
5
namespace GraphQL\Error;
6
7
use GraphQL\Language\AST\Node;
8
use GraphQL\Language\Source;
9
use GraphQL\Language\SourceLocation;
10
use GraphQL\Utils\Utils;
11
use function array_filter;
12
use function array_map;
13
use function array_merge;
14
use function is_array;
15
use function iterator_to_array;
16
17
/**
18
 * Describes an Error found during the parse, validate, or
19
 * execute phases of performing a GraphQL operation. In addition to a message
20
 * and stack trace, it also includes information about the locations in a
21
 * GraphQL document and/or execution result that correspond to the Error.
22
 *
23
 * When the error was caused by an exception thrown in resolver, original exception
24
 * is available via `getPrevious()`.
25
 *
26
 * Also read related docs on [error handling](error-handling.md)
27
 *
28
 * Class extends standard PHP `\Exception`, so all standard methods of base `\Exception` class
29
 * are available in addition to those listed below.
30
 */
31
class Error extends \Exception implements \JsonSerializable, ClientAware
32
{
33
    const CATEGORY_GRAPHQL  = 'graphql';
34
    const CATEGORY_INTERNAL = 'internal';
35
36
    /**
37
     * A message describing the Error for debugging purposes.
38
     *
39
     * @var string
40
     */
41
    public $message;
42
43
    /** @var SourceLocation[] */
44
    private $locations;
45
46
    /**
47
     * An array describing the JSON-path into the execution response which
48
     * corresponds to this error. Only included for errors during execution.
49
     *
50
     * @var mixed[]|null
51
     */
52
    public $path;
53
54
    /**
55
     * An array of GraphQL AST Nodes corresponding to this error.
56
     *
57
     * @var Node[]|null
58
     */
59
    public $nodes;
60
61
    /**
62
     * The source GraphQL document for the first location of this error.
63
     *
64
     * Note that if this Error represents more than one node, the source may not
65
     * represent nodes after the first node.
66
     *
67
     * @var Source|null
68
     */
69
    private $source;
70
71
    /** @var int[]|null */
72
    private $positions;
73
74
    /** @var bool */
75
    private $isClientSafe;
76
77
    /** @var string */
78
    protected $category;
79
80
    /** @var mixed[]|null */
81
    protected $extensions;
82
83
    /**
84
     * @param string       $message
85
     * @param Node[]|null  $nodes
86
     * @param mixed[]|null $positions
87
     * @param mixed[]|null $path
88
     * @param \Throwable   $previous
89
     * @param mixed[]      $extensions
90
     */
91 470
    public function __construct(
92
        $message,
93
        $nodes = null,
94
        ?Source $source = null,
95
        $positions = null,
96
        $path = null,
97
        $previous = null,
98
        array $extensions = []
99
    ) {
100 470
        parent::__construct($message, 0, $previous);
101
102
        // Compute list of blame nodes.
103 470
        if ($nodes instanceof \Traversable) {
104 47
            $nodes = iterator_to_array($nodes);
105 429
        } elseif ($nodes && ! is_array($nodes)) {
0 ignored issues
show
introduced by
The condition is_array($nodes) is always true.
Loading history...
106 64
            $nodes = [$nodes];
107
        }
108
109 470
        $this->nodes      = $nodes;
110 470
        $this->source     = $source;
111 470
        $this->positions  = $positions;
112 470
        $this->path       = $path;
113 470
        $this->extensions = $extensions ?: (
114 469
        $previous && $previous instanceof self
115 31
            ? $previous->extensions
116 469
            : []
117
        );
118
119 470
        if ($previous instanceof ClientAware) {
120 60
            $this->isClientSafe = $previous->isClientSafe();
121 60
            $this->category     = $previous->getCategory() ?: static::CATEGORY_INTERNAL;
122 447
        } elseif ($previous) {
123 59
            $this->isClientSafe = false;
124 59
            $this->category     = static::CATEGORY_INTERNAL;
125
        } else {
126 393
            $this->isClientSafe = true;
127 393
            $this->category     = static::CATEGORY_GRAPHQL;
128
        }
129 470
    }
130
131
    /**
132
     * Given an arbitrary Error, presumably thrown while attempting to execute a
133
     * GraphQL operation, produce a new GraphQLError aware of the location in the
134
     * document responsible for the original Error.
135
     *
136
     * @param mixed        $error
137
     * @param Node[]|null  $nodes
138
     * @param mixed[]|null $path
139
     * @return Error
140
     */
141 55
    public static function createLocatedError($error, $nodes = null, $path = null)
142
    {
143 55
        if ($error instanceof self) {
144 23
            if ($error->path && $error->nodes) {
145 18
                return $error;
146
            } else {
147 5
                $nodes = $nodes ?: $error->nodes;
148 5
                $path  = $path ?: $error->path;
149
            }
150
        }
151
152 55
        $source     = $positions = $originalError = null;
153 55
        $extensions = [];
154
155 55
        if ($error instanceof self) {
156 5
            $message       = $error->getMessage();
157 5
            $originalError = $error;
158 5
            $nodes         = $error->nodes ?: $nodes;
159 5
            $source        = $error->source;
160 5
            $positions     = $error->positions;
161 5
            $extensions    = $error->extensions;
162 50
        } elseif ($error instanceof \Exception || $error instanceof \Throwable) {
163 50
            $message       = $error->getMessage();
164 50
            $originalError = $error;
165
        } else {
166
            $message = (string) $error;
167
        }
168
169 55
        return new static(
170 55
            $message ?: 'An unknown error occurred.',
171 55
            $nodes,
172 55
            $source,
173 55
            $positions,
174 55
            $path,
175 55
            $originalError,
176 55
            $extensions
0 ignored issues
show
Bug introduced by
It seems like $extensions can also be of type null; however, parameter $extensions of GraphQL\Error\Error::__construct() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

176
            /** @scrutinizer ignore-type */ $extensions
Loading history...
177
        );
178
    }
179
180
    /**
181
     * @return mixed[]
182
     */
183 194
    public static function formatError(Error $error)
184
    {
185 194
        return $error->toSerializableArray();
0 ignored issues
show
Deprecated Code introduced by
The function GraphQL\Error\Error::toSerializableArray() has been deprecated: Use FormattedError::createFromException() instead ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

185
        return /** @scrutinizer ignore-deprecated */ $error->toSerializableArray();

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
186
    }
187
188
    /**
189
     * @inheritdoc
190
     */
191 86
    public function isClientSafe()
192
    {
193 86
        return $this->isClientSafe;
194
    }
195
196
    /**
197
     * @inheritdoc
198
     */
199 85
    public function getCategory()
200
    {
201 85
        return $this->category;
202
    }
203
204
    /**
205
     * @return Source|null
206
     */
207 382
    public function getSource()
208
    {
209 382
        if ($this->source === null) {
210 327
            if (! empty($this->nodes[0]) && ! empty($this->nodes[0]->loc)) {
211 270
                $this->source = $this->nodes[0]->loc->source;
212
            }
213
        }
214
215 382
        return $this->source;
216
    }
217
218
    /**
219
     * @return int[]
220
     */
221 381
    public function getPositions()
222
    {
223 381
        if ($this->positions === null && ! empty($this->nodes)) {
224 279
            $positions = array_map(
225
                function ($node) {
226 279
                    return isset($node->loc) ? $node->loc->start : null;
227 279
                },
228 279
                $this->nodes
229
            );
230
231 279
            $this->positions = array_filter(
232 279
                $positions,
233
                function ($p) {
234 279
                    return $p !== null;
235 279
                }
236
            );
237
        }
238
239 381
        return $this->positions;
240
    }
241
242
    /**
243
     * An array of locations within the source GraphQL document which correspond to this error.
244
     *
245
     * Each entry has information about `line` and `column` within source GraphQL document:
246
     * $location->line;
247
     * $location->column;
248
     *
249
     * Errors during validation often contain multiple locations, for example to
250
     * point out to field mentioned in multiple fragments. Errors during execution include a
251
     * single location, the field which produced the error.
252
     *
253
     * @api
254
     * @return SourceLocation[]
255
     */
256 372
    public function getLocations()
257
    {
258 372
        if ($this->locations === null) {
259 372
            $positions = $this->getPositions();
260 372
            $source    = $this->getSource();
261 372
            $nodes     = $this->nodes;
262
263 372
            if ($positions && $source) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $positions of type integer[] is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
264 324
                $this->locations = array_map(
265
                    function ($pos) use ($source) {
266 324
                        return $source->getLocation($pos);
267 324
                    },
268 324
                    $positions
269
                );
270 50
            } elseif ($nodes) {
271 1
                $this->locations = array_filter(
272 1
                    array_map(
273
                        function ($node) {
274 1
                            if ($node->loc) {
275 1
                                return $node->loc->source->getLocation($node->loc->start);
276
                            }
277 1
                        },
278 1
                        $nodes
279
                    )
280
                );
281
            } else {
282 50
                $this->locations = [];
283
            }
284
        }
285
286 372
        return $this->locations;
287
    }
288
289
    /**
290
     * @return Node[]|null
291
     */
292 16
    public function getNodes()
293
    {
294 16
        return $this->nodes;
295
    }
296
297
    /**
298
     * Returns an array describing the path from the root value to the field which produced this error.
299
     * Only included for execution errors.
300
     *
301
     * @api
302
     * @return mixed[]|null
303
     */
304 17
    public function getPath()
305
    {
306 17
        return $this->path;
307
    }
308
309
    /**
310
     * @return mixed[]
311
     */
312 273
    public function getExtensions()
313
    {
314 273
        return $this->extensions;
315
    }
316
317
    /**
318
     * Returns array representation of error suitable for serialization
319
     *
320
     * @deprecated Use FormattedError::createFromException() instead
321
     * @return mixed[]
322
     */
323
    public function toSerializableArray()
324
    {
325
        $arr = [
326
            'message' => $this->getMessage(),
327
        ];
328
329
        if ($this->getExtensions()) {
330
            $arr = array_merge($this->getExtensions(), $arr);
331
        }
332
333
        $locations = Utils::map(
334
            $this->getLocations(),
335
            function (SourceLocation $loc) {
336
                return $loc->toSerializableArray();
337
            }
338
        );
339
340
        if (! empty($locations)) {
341
            $arr['locations'] = $locations;
342
        }
343
        if (! empty($this->path)) {
344
            $arr['path'] = $this->path;
345
        }
346
347
        return $arr;
348
    }
349
350
    /**
351
     * Specify data which should be serialized to JSON
352
     * @link http://php.net/manual/en/jsonserializable.jsonserialize.php
353
     * @return mixed data which can be serialized by <b>json_encode</b>,
354
     * which is a value of any type other than a resource.
355
     */
356
    public function jsonSerialize()
357
    {
358
        return $this->toSerializableArray();
0 ignored issues
show
Deprecated Code introduced by
The function GraphQL\Error\Error::toSerializableArray() has been deprecated: Use FormattedError::createFromException() instead ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

358
        return /** @scrutinizer ignore-deprecated */ $this->toSerializableArray();

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
359
    }
360
361
    /**
362
     * @return string
363
     */
364 10
    public function __toString()
365
    {
366 10
        return FormattedError::printError($this);
367
    }
368
}
369