Scrutinizer GitHub App not installed

We could not synchronize checks via GitHub's checks API since Scrutinizer's GitHub App is not installed for this repository.

Install GitHub App

Passed
Pull Request — master (#275)
by Hugo
15:12
created

ErrorHandler::logException()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 13
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 13
ccs 10
cts 10
cp 1
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 9
nc 1
nop 2
crap 1
1
<?php
2
3
namespace Overblog\GraphQLBundle\Error;
4
5
use GraphQL\Error\ClientAware;
6
use GraphQL\Error\Debug;
7
use GraphQL\Error\Error as GraphQLError;
8
use GraphQL\Error\FormattedError;
9
use GraphQL\Error\UserError as GraphQLUserError;
10
use GraphQL\Executor\ExecutionResult;
11
use Overblog\GraphQLBundle\Event\ErrorFormattingEvent;
12
use Overblog\GraphQLBundle\Event\Events;
13
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
14
15
class ErrorHandler
16
{
17
    const DEFAULT_ERROR_MESSAGE = 'Internal server Error';
18
19
    /** @var EventDispatcherInterface */
20
    private $dispatcher;
21
22
    /** @var string */
23
    private $internalErrorMessage;
24
25
    /** @var array */
26
    private $exceptionMap;
27
28
    /** @var bool */
29
    private $mapExceptionsToParent;
30
31 74
    public function __construct(
32
        EventDispatcherInterface $dispatcher,
33
        $internalErrorMessage = null,
34
        array $exceptionMap = [],
35
        $mapExceptionsToParent = false
36
    ) {
37 74
        $this->dispatcher = $dispatcher;
38 74
        if (empty($internalErrorMessage)) {
39 15
            $internalErrorMessage = self::DEFAULT_ERROR_MESSAGE;
40
        }
41 74
        $this->internalErrorMessage = $internalErrorMessage;
42 74
        $this->exceptionMap = $exceptionMap;
43 74
        $this->mapExceptionsToParent = $mapExceptionsToParent;
44 74
    }
45
46 73
    public function handleErrors(ExecutionResult $executionResult, $throwRawException = false, $debug = false)
47
    {
48 73
        $errorFormatter = $this->createErrorFormatter($debug);
49 73
        $executionResult->setErrorFormatter($errorFormatter);
50 73
        $exceptions = $this->treatExceptions($executionResult->errors, $throwRawException);
51 70
        $executionResult->errors = $exceptions['errors'];
52 70
        if (!empty($exceptions['extensions']['warnings'])) {
53 7
            $executionResult->extensions['warnings'] = array_map($errorFormatter, $exceptions['extensions']['warnings']);
54
        }
55 70
    }
56
57 73
    private function createErrorFormatter($debug = false)
58
    {
59 73
        $debugMode = false;
60 73
        if ($debug) {
61 1
            $debugMode = Debug::INCLUDE_TRACE | Debug::INCLUDE_DEBUG_MESSAGE;
62
        }
63
64 73
        return function (GraphQLError $error) use ($debugMode) {
65 23
            $event = new ErrorFormattingEvent($error, FormattedError::createFromException($error, $debugMode, $this->internalErrorMessage));
0 ignored issues
show
Documentation introduced by
$error is of type object<GraphQL\Error\Error>, but the function expects a object<Throwable>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
66 23
            $this->dispatcher->dispatch(Events::ERROR_FORMATTING, $event);
67
68 23
            return $event->getFormattedError()->getArrayCopy();
69 73
        };
70
    }
71
72
    /**
73
     * @param GraphQLError[] $errors
74
     * @param bool           $throwRawException
75
     *
76
     * @return array
77
     *
78
     * @throws \Error|\Exception
79
     */
80 73
    private function treatExceptions(array $errors, $throwRawException)
81
    {
82
        $treatedExceptions = [
83 73
            'errors' => [],
84
            'extensions' => [
85
                'warnings' => [],
86
            ],
87
        ];
88
89
        /** @var GraphQLError $error */
90 73
        foreach ($this->flattenErrors($errors) as $error) {
91 26
            $rawException = $this->convertException($error->getPrevious());
92
93
            // raw GraphQL Error or InvariantViolation exception
94 26
            if (null === $rawException) {
95 9
                $treatedExceptions['errors'][] = $error;
96 9
                continue;
97
            }
98
99
            // recreate a error with converted exception
100 18
            $errorWithConvertedException = new GraphQLError(
101 18
                $error->getMessage(),
102 18
                $error->nodes,
103 18
                $error->getSource(),
104 18
                $error->getPositions(),
105 18
                $error->path,
106 18
                $rawException
107
            );
108
109
            // user error
110 18
            if ($rawException instanceof GraphQLUserError) {
111 8
                $treatedExceptions['errors'][] = $errorWithConvertedException;
112 8
                continue;
113
            }
114
115
            // user warning
116 11
            if ($rawException instanceof UserWarning) {
117 7
                $treatedExceptions['extensions']['warnings'][] = $errorWithConvertedException;
118 7
                continue;
119
            }
120
121
            // if is a catch exception wrapped in Error
122 5
            if ($throwRawException) {
123 3
                throw $rawException;
124
            }
125
126 2
            $treatedExceptions['errors'][] = $errorWithConvertedException;
127
        }
128
129 70
        return $treatedExceptions;
130
    }
131
132
    /**
133
     * @param GraphQLError[] $errors
134
     *
135
     * @return GraphQLError[]
136
     */
137 73
    private function flattenErrors(array $errors)
138
    {
139 73
        $flattenErrors = [];
140
141 73
        foreach ($errors as $error) {
142 26
            $rawException = $error->getPrevious();
143
            // multiple errors
144 26
            if ($rawException instanceof UserErrors) {
145 1
                $rawExceptions = $rawException;
146 1
                foreach ($rawExceptions->getErrors() as $rawException) {
147 1
                    $flattenErrors[] = GraphQLError::createLocatedError($rawException, $error->nodes, $error->path);
148
                }
149
            } else {
150 26
                $flattenErrors[] = $error;
151
            }
152
        }
153
154 73
        return $flattenErrors;
155
    }
156
157
    /**
158
     * Tries to convert a raw exception into a user warning or error
159
     * that is displayed to the user.
160
     *
161
     * @param \Exception|\Error $rawException
162
     *
163
     * @return \Exception|\Error
164
     */
165 26
    private function convertException($rawException = null)
166
    {
167 26
        if (null === $rawException || $rawException instanceof ClientAware) {
168 14
            return $rawException;
169
        }
170
171 13
        $errorClass = $this->findErrorClass($rawException);
172 13
        if (null !== $errorClass) {
173 8
            return new $errorClass($rawException->getMessage(), $rawException->getCode(), $rawException);
174
        }
175
176 5
        return $rawException;
177
    }
178
179
    /**
180
     * @param \Exception|\Error $rawException
181
     *
182
     * @return string|null
183
     */
184 13
    private function findErrorClass($rawException)
185
    {
186 13
        $rawExceptionClass = get_class($rawException);
187 13
        if (isset($this->exceptionMap[$rawExceptionClass])) {
188 7
            return $this->exceptionMap[$rawExceptionClass];
189
        }
190
191 6
        if ($this->mapExceptionsToParent) {
192 2
            return $this->findErrorClassUsingParentException($rawException);
193
        }
194
195 4
        return null;
196
    }
197
198
    /**
199
     * @param \Exception|\Error $rawException
200
     *
201
     * @return string|null
202
     */
203 2
    private function findErrorClassUsingParentException($rawException)
204
    {
205 2
        foreach ($this->exceptionMap as $rawExceptionClass => $errorClass) {
206 1
            if ($rawException instanceof $rawExceptionClass) {
207 1
                return $errorClass;
208
            }
209
        }
210
211 1
        return null;
212
    }
213
}
214