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
04:38
created

ErrorHandler   A

Complexity

Total Complexity 22

Size/Duplication

Total Lines 171
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Test Coverage

Coverage 90.14%

Importance

Changes 0
Metric Value
wmc 22
c 0
b 0
f 0
lcom 1
cbo 3
dl 0
loc 171
ccs 64
cts 71
cp 0.9014
rs 10

7 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 9 3
A logException() 0 13 1
A handleErrors() 0 9 2
A convertException() 0 15 3
A setUserWarningClass() 0 6 1
A setUserErrorClass() 0 6 1
C treatExceptions() 0 65 11
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 5
    public function __construct($internalErrorMessage = null, LoggerInterface $logger = null, array $exceptionMap = [])
34
    {
35 5
        $this->logger = (null === $logger) ? new NullLogger() : $logger;
36 5
        if (empty($internalErrorMessage)) {
37 5
            $internalErrorMessage = self::DEFAULT_ERROR_MESSAGE;
38
        }
39 5
        $this->internalErrorMessage = $internalErrorMessage;
40 5
        $this->exceptionMap = $exceptionMap;
41 5
    }
42
43
    public function setUserWarningClass($userWarningClass)
44
    {
45
        $this->userWarningClass = $userWarningClass;
46
47
        return $this;
48
    }
49
50
    public function setUserErrorClass($userErrorClass)
51
    {
52
        $this->userErrorClass = $userErrorClass;
53
54
        return $this;
55
    }
56
57
    /**
58
     * @param GraphQLError[] $errors
59
     * @param bool           $throwRawException
60
     *
61
     * @return array
62
     *
63
     * @throws \Exception
64
     */
65 5
    protected function treatExceptions(array $errors, $throwRawException)
66
    {
67
        $treatedExceptions = [
68 5
            'errors' => [],
69
            'extensions' => [
70
                'warnings' => [],
71
            ],
72
        ];
73
74
        /** @var GraphQLError $error */
75 5
        foreach ($errors as $error) {
76 5
            $rawException = $this->convertException($error->getPrevious());
77
78
            // raw GraphQL Error or InvariantViolation exception
79 5
            if (null === $rawException || $rawException instanceof GraphQLUserError) {
80 2
                $treatedExceptions['errors'][] = $error;
81 2
                continue;
82
            }
83
84
            // user error
85 4
            if ($rawException instanceof $this->userErrorClass) {
86 2
                $treatedExceptions['errors'][] = $error;
87 2
                if ($rawException->getPrevious()) {
88
                    $this->logException($rawException->getPrevious());
89
                }
90 2
                continue;
91
            }
92
93
            // user warning
94 3
            if ($rawException instanceof $this->userWarningClass) {
95 2
                $treatedExceptions['extensions']['warnings'][] = $error;
96 2
                if ($rawException->getPrevious()) {
97 1
                    $this->logException($rawException->getPrevious(), LogLevel::WARNING);
98
                }
99 2
                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 4
        return $treatedExceptions;
129
    }
130
131
    /**
132
     * @param \Exception|\Error $exception
133
     * @param string            $errorLevel
134
     */
135 2
    public function logException($exception, $errorLevel = LogLevel::ERROR)
136
    {
137 2
        $message = sprintf(
138 2
            '%s: %s[%d] (caught exception) at %s line %s.',
139 2
            get_class($exception),
140 2
            $exception->getMessage(),
141 2
            $exception->getCode(),
142 2
            $exception->getFile(),
143 2
            $exception->getLine()
144
        );
145
146 2
        $this->logger->$errorLevel($message, ['exception' => $exception]);
147 2
    }
148
149 5
    public function handleErrors(ExecutionResult $executionResult, $throwRawException = false)
150
    {
151 5
        $executionResult->setErrorFormatter(sprintf('\%s::formatError', GraphQLError::class));
152 5
        $exceptions = $this->treatExceptions($executionResult->errors, $throwRawException);
153 4
        $executionResult->errors = $exceptions['errors'];
154 4
        if (!empty($exceptions['extensions']['warnings'])) {
155 2
            $executionResult->extensions['warnings'] = array_map([GraphQLError::class, 'formatError'], $exceptions['extensions']['warnings']);
156
        }
157 4
    }
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 5
    protected function convertException($rawException = null)
168
    {
169 5
        if (null === $rawException) {
170 2
            return;
171
        }
172
173 4
        $rawExceptionClass = get_class($rawException);
174 4
        if (isset($this->exceptionMap[$rawExceptionClass])) {
175 1
            $errorClass = $this->exceptionMap[$rawExceptionClass];
176
177 1
            return new $errorClass($rawException->getMessage(), $rawException->getCode(), $rawException);
178
        }
179
180 3
        return $rawException;
181
    }
182
}
183