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 (#234)
by Jérémiah
07:13
created

ErrorHandler::__construct()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 9
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 3

Importance

Changes 0
Metric Value
dl 0
loc 9
ccs 7
cts 7
cp 1
rs 9.6666
c 0
b 0
f 0
cc 3
eloc 6
nc 4
nop 3
crap 3
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 76
    public function __construct($internalErrorMessage = null, LoggerInterface $logger = null, array $exceptionMap = [])
34
    {
35 76
        $this->logger = (null === $logger) ? new NullLogger() : $logger;
36 76
        if (empty($internalErrorMessage)) {
37 69
            $internalErrorMessage = self::DEFAULT_ERROR_MESSAGE;
38
        }
39 76
        $this->internalErrorMessage = $internalErrorMessage;
40 76
        $this->exceptionMap = $exceptionMap;
41 76
    }
42
43 71
    public function setUserWarningClass($userWarningClass)
44
    {
45 71
        $this->userWarningClass = $userWarningClass;
46
47 71
        return $this;
48
    }
49
50 71
    public function setUserErrorClass($userErrorClass)
51
    {
52 71
        $this->userErrorClass = $userErrorClass;
53
54 71
        return $this;
55
    }
56
57
    /**
58
     * @param GraphQLError[] $errors
59
     * @param bool           $throwRawException
60
     *
61
     * @return array
62
     *
63
     * @throws \Exception
64
     */
65 62
    protected function treatExceptions(array $errors, $throwRawException)
66
    {
67
        $treatedExceptions = [
68 62
            'errors' => [],
69
            'extensions' => [
70
                'warnings' => [],
71
            ],
72
        ];
73
74
        /** @var GraphQLError $error */
75 62
        foreach ($errors as $error) {
76 17
            $rawException = $this->convertException($error->getPrevious());
77
78
            // raw GraphQL Error or InvariantViolation exception
79 17
            if (null === $rawException || $rawException instanceof GraphQLUserError) {
80 9
                $treatedExceptions['errors'][] = $error;
81 9
                continue;
82
            }
83
84
            // user error
85 9
            if ($rawException instanceof $this->userErrorClass) {
86 4
                $treatedExceptions['errors'][] = $error;
87 4
                if ($rawException->getPrevious()) {
88 1
                    $this->logException($rawException->getPrevious());
89
                }
90 4
                continue;
91
            }
92
93
            // user warning
94 6
            if ($rawException instanceof $this->userWarningClass) {
95 5
                $treatedExceptions['extensions']['warnings'][] = $error;
96 5
                if ($rawException->getPrevious()) {
97 1
                    $this->logException($rawException->getPrevious(), LogLevel::WARNING);
98
                }
99 5
                continue;
100
            }
101
102
            // multiple errors
103 2
            if ($rawException instanceof UserErrors) {
104 1
                $rawExceptions = $rawException;
105 1
                foreach ($rawExceptions->getErrors() as $rawException) {
106 1
                    $treatedExceptions['errors'][] = GraphQLError::createLocatedError($rawException, $error->nodes);
107
                }
108 1
                continue;
109
            }
110
111
            // if is a try catch exception wrapped in Error
112 2
            if ($throwRawException) {
113 1
                throw $rawException;
114
            }
115
116 1
            $this->logException($rawException, LogLevel::CRITICAL);
117
118 1
            $treatedExceptions['errors'][] = new GraphQLError(
119 1
                $this->internalErrorMessage,
120 1
                $error->nodes,
121 1
                $error->getSource(),
122 1
                $error->getPositions(),
123 1
                $error->path,
124 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...
125
            );
126
        }
127
128 61
        return $treatedExceptions;
129
    }
130
131
    /**
132
     * @param \Exception|\Error $exception
133
     * @param string            $errorLevel
134
     */
135 3
    public function logException($exception, $errorLevel = LogLevel::ERROR)
136
    {
137 3
        $message = sprintf(
138 3
            '%s: %s[%d] (caught exception) at %s line %s.',
139 3
            get_class($exception),
140 3
            $exception->getMessage(),
141 3
            $exception->getCode(),
142 3
            $exception->getFile(),
143 3
            $exception->getLine()
144
        );
145
146 3
        $this->logger->$errorLevel($message, ['exception' => $exception]);
147 3
    }
148
149 62
    public function handleErrors(ExecutionResult $executionResult, $throwRawException = false)
150
    {
151 62
        $executionResult->setErrorFormatter(sprintf('\%s::formatError', GraphQLError::class));
152 62
        $exceptions = $this->treatExceptions($executionResult->errors, $throwRawException);
153 61
        $executionResult->errors = $exceptions['errors'];
154 61
        if (!empty($exceptions['extensions']['warnings'])) {
155 5
            $executionResult->extensions['warnings'] = array_map([GraphQLError::class, 'formatError'], $exceptions['extensions']['warnings']);
156
        }
157 61
    }
158
159
    /**
160
     * Tries to convert a raw exception into a user warning or error
161
     * that is displayed to the user.
162
     *
163
     * @param \Exception|\Error $rawException
164
     *
165
     * @return \Exception|\Error
166
     */
167 17
    protected function convertException($rawException = null)
168
    {
169 17
        if (null === $rawException) {
170 9
            return;
171
        }
172
173 9
        $rawExceptionClass = get_class($rawException);
174 9
        if (isset($this->exceptionMap[$rawExceptionClass])) {
175 2
            $errorClass = $this->exceptionMap[$rawExceptionClass];
176
177 2
            return new $errorClass($rawException->getMessage(), $rawException->getCode(), $rawException);
178
        }
179
180 7
        return $rawException;
181
    }
182
}
183