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 (#236)
by Herberto
09:02 queued 03:03
created

ErrorHandler::findErrorClassUsingParentException()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 10
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 3.072

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 10
ccs 4
cts 5
cp 0.8
rs 9.4285
cc 3
eloc 5
nc 3
nop 1
crap 3.072
1
<?php
2
3
namespace Overblog\GraphQLBundle\Error;
4
5
use GraphQL\Error\Error as GraphQLError;
6
use GraphQL\Error\UserError as GraphQLUserError;
7
use GraphQL\Executor\ExecutionResult;
8
use Psr\Log\LoggerInterface;
9
use Psr\Log\LogLevel;
10
use Psr\Log\NullLogger;
11
12
class ErrorHandler
13
{
14
    const DEFAULT_ERROR_MESSAGE = 'Internal server Error';
15
    const DEFAULT_USER_WARNING_CLASS = UserWarning::class;
16
    const DEFAULT_USER_ERROR_CLASS = UserError::class;
17
18
    /** @var LoggerInterface */
19
    private $logger;
20
21
    /** @var string */
22
    private $internalErrorMessage;
23
24
    /** @var array */
25
    private $exceptionMap;
26
27
    /** @var string */
28
    private $userWarningClass = self::DEFAULT_USER_WARNING_CLASS;
29
30
    /** @var string */
31
    private $userErrorClass = self::DEFAULT_USER_ERROR_CLASS;
32
33
    /** @var bool */
34
    private $mapExceptionsToParent;
35
36 83
    public function __construct(
37
        $internalErrorMessage = null,
38
        LoggerInterface $logger = null,
39
        array $exceptionMap = [],
40
        $mapExceptionsToParent = false
41
    ) {
42 83
        $this->logger = (null === $logger) ? new NullLogger() : $logger;
43 83
        if (empty($internalErrorMessage)) {
44 76
            $internalErrorMessage = self::DEFAULT_ERROR_MESSAGE;
45
        }
46 83
        $this->internalErrorMessage = $internalErrorMessage;
47 83
        $this->exceptionMap = $exceptionMap;
48 83
        $this->mapExceptionsToParent = $mapExceptionsToParent;
49 83
    }
50
51 71
    public function setUserWarningClass($userWarningClass)
52
    {
53 71
        $this->userWarningClass = $userWarningClass;
54
55 71
        return $this;
56
    }
57
58 71
    public function setUserErrorClass($userErrorClass)
59
    {
60 71
        $this->userErrorClass = $userErrorClass;
61
62 71
        return $this;
63
    }
64
65
    /**
66
     * @param GraphQLError[] $errors
67
     * @param bool           $throwRawException
68
     *
69
     * @return array
70
     *
71
     * @throws \Exception
72
     */
73 69
    protected function treatExceptions(array $errors, $throwRawException)
74
    {
75
        $treatedExceptions = [
76 69
            'errors' => [],
77
            'extensions' => [
78
                'warnings' => [],
79
            ],
80
        ];
81
82
        /** @var GraphQLError $error */
83 69
        foreach ($errors as $error) {
84 24
            $rawException = $this->convertException($error->getPrevious());
85
86
            // raw GraphQL Error or InvariantViolation exception
87 24
            if (null === $rawException || $rawException instanceof GraphQLUserError) {
88 9
                $treatedExceptions['errors'][] = $error;
89 9
                continue;
90
            }
91
92
            // user error
93 16
            if ($rawException instanceof $this->userErrorClass) {
94 8
                $treatedExceptions['errors'][] = $error;
95 8
                if ($rawException->getPrevious()) {
96 5
                    $this->logException($rawException->getPrevious());
97
                }
98 8
                continue;
99
            }
100
101
            // user warning
102 9
            if ($rawException instanceof $this->userWarningClass) {
103 7
                $treatedExceptions['extensions']['warnings'][] = $error;
104 7
                if ($rawException->getPrevious()) {
105 3
                    $this->logException($rawException->getPrevious(), LogLevel::WARNING);
106
                }
107 7
                continue;
108
            }
109
110
            // multiple errors
111 3
            if ($rawException instanceof UserErrors) {
112 1
                $rawExceptions = $rawException;
113 1
                foreach ($rawExceptions->getErrors() as $rawException) {
114 1
                    $treatedExceptions['errors'][] = GraphQLError::createLocatedError($rawException, $error->nodes);
115
                }
116 1
                continue;
117
            }
118
119
            // if is a try catch exception wrapped in Error
120 3
            if ($throwRawException) {
121 2
                throw $rawException;
122
            }
123
124 1
            $this->logException($rawException, LogLevel::CRITICAL);
125
126 1
            $treatedExceptions['errors'][] = new GraphQLError(
127 1
                $this->internalErrorMessage,
128 1
                $error->nodes,
129 1
                $error->getSource(),
130 1
                $error->getPositions(),
131 1
                $error->path,
132 1
                $rawException
0 ignored issues
show
Documentation introduced by
$rawException is of type object<Exception>, but the function expects a object<Throwable>|null.

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...
133
            );
134
        }
135
136 67
        return $treatedExceptions;
137
    }
138
139
    /**
140
     * @param \Exception|\Error $exception
141
     * @param string            $errorLevel
142
     */
143 9
    public function logException($exception, $errorLevel = LogLevel::ERROR)
144
    {
145 9
        $message = sprintf(
146 9
            '%s: %s[%d] (caught exception) at %s line %s.',
147 9
            get_class($exception),
148 9
            $exception->getMessage(),
149 9
            $exception->getCode(),
150 9
            $exception->getFile(),
151 9
            $exception->getLine()
152
        );
153
154 9
        $this->logger->$errorLevel($message, ['exception' => $exception]);
155 9
    }
156
157 69
    public function handleErrors(ExecutionResult $executionResult, $throwRawException = false)
158
    {
159 69
        $executionResult->setErrorFormatter(sprintf('\%s::formatError', GraphQLError::class));
160 69
        $exceptions = $this->treatExceptions($executionResult->errors, $throwRawException);
161 67
        $executionResult->errors = $exceptions['errors'];
162 67
        if (!empty($exceptions['extensions']['warnings'])) {
163 7
            $executionResult->extensions['warnings'] = array_map([GraphQLError::class, 'formatError'], $exceptions['extensions']['warnings']);
164
        }
165 67
    }
166
167
    /**
168
     * Tries to convert a raw exception into a user warning or error
169
     * that is displayed to the user.
170
     *
171
     * @param \Exception|\Error $rawException
172
     *
173
     * @return \Exception|\Error
174
     */
175 24
    protected function convertException($rawException = null)
176
    {
177 24
        if (null === $rawException) {
178 9
            return;
179
        }
180
181 16
        $errorClass = $this->findErrorClass($rawException);
182 16
        if (null !== $errorClass) {
183 8
            return new $errorClass($rawException->getMessage(), $rawException->getCode(), $rawException);
184
        }
185
186 8
        return $rawException;
187
    }
188
189
    /**
190
     * @param \Exception|\Error $rawException
191
     *
192
     * @return string|null
193
     */
194 16
    private function findErrorClass($rawException)
195
    {
196 16
        $rawExceptionClass = get_class($rawException);
197 16
        if (isset($this->exceptionMap[$rawExceptionClass])) {
198 7
            return $this->exceptionMap[$rawExceptionClass];
199
        }
200
201 9
        if ($this->mapExceptionsToParent) {
202 1
            return $this->findErrorClassUsingParentException($rawException);
203
        }
204
205 8
        return null;
206
    }
207
208
    /**
209
     * @param \Exception|\Error $rawException
210
     *
211
     * @return string|null
212
     */
213 1
    private function findErrorClassUsingParentException($rawException)
214
    {
215 1
        foreach ($this->exceptionMap as $rawExceptionClass => $errorClass) {
216 1
            if ($rawException instanceof $rawExceptionClass) {
217 1
                return $errorClass;
218
            }
219
        }
220
221
        return null;
222
    }
223
}
224