ExceptionHandler::shouldReport()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 1
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php namespace EvolutionCMS;
2
3
use Illuminate\Contracts\Container\Container;
4
use AgelxNash\Modx\Evo\Database\Exceptions\ConnectException;
5
use Exception;
6
use Symfony\Component\Debug\Exception\FatalErrorException;
7
use Symfony\Component\Debug\Exception\FatalThrowableError;
8
use EvolutionCMS\Tracy\Debugger;
9
use EvolutionCMS\Interfaces\TracyPanel;
10
11
/**
12
 * @see: https://github.com/laravel/framework/blob/5.6/src/Illuminate/Foundation/Bootstrap/HandleExceptions.php
13
 */
14
class ExceptionHandler
15
{
16
    /**
17
     * Create a new exception handler instance.
18
     *
19
     * @param  Container $container
20
     * @return void
0 ignored issues
show
Comprehensibility Best Practice introduced by
Adding a @return annotation to constructors is generally not recommended as a constructor does not have a meaningful return value.

Adding a @return annotation to a constructor is not recommended, since a constructor does not have a meaningful return value.

Please refer to the PHP core documentation on constructors.

Loading history...
21
     */
22
    public function __construct(Container $container)
23
    {
24
        $this->container = $container;
0 ignored issues
show
Bug introduced by
The property container does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
25
26
        Debugger::enable(
27
            ! $this->container['config']->get('tracy.active'),
28
            evolutionCMS()->storagePath() . '/logs'
29
        );
30
        Debugger::$strictMode = false;
31
        Debugger::$showLocation = true;
32
        //Debugger::$logSeverity = E_NOTICE | E_WARNING;
33
34
        $this->injectTracyPanels();
35
    }
36
37
    protected function injectTracyPanels() : void
38
    {
39
        foreach ($this->container['config']->get('tracy.panels') as $panel) {
40
            $panel = new $panel;
41
            if (is_a($panel, TracyPanel::class)) {
42
                $panel->setEvolutionCMS($this->container);
43
            }
44
            Debugger::getBar()->addPanel($panel);
45
        }
46
    }
47
48
    /**
49
     * Handle the PHP shutdown event.
50
     *
51
     * @deprecated
52
     * @return void
53
     */
54
    public function handleShutdown()
55
    {
56
        if (!is_null($error = error_get_last()) && $this->isFatal($error['type'])) {
57
            $this->handleException($this->fatalExceptionFromError($error, 0));
0 ignored issues
show
Deprecated Code introduced by
The method EvolutionCMS\ExceptionHandler::handleException() has been deprecated.

This method has been deprecated.

Loading history...
58
        }
59
    }
60
61
    /**
62
     * Create a new fatal exception instance from an error array.
63
     *
64
     * @param  array $error
65
     * @param  int|null $traceOffset
66
     * @return \Symfony\Component\Debug\Exception\FatalErrorException
67
     */
68
    protected function fatalExceptionFromError(array $error, $traceOffset = null)
69
    {
70
        return new FatalErrorException(
71
            $error['message'], $error['type'], 0, $error['file'], $error['line'], $traceOffset
72
        );
73
    }
74
75
    /**
76
     * Determine if the error type is fatal.
77
     *
78
     * @param  int $type
79
     * @return bool
80
     */
81
    protected function isFatal($type)
82
    {
83
        return in_array($type, [E_COMPILE_ERROR, E_CORE_ERROR, E_ERROR, E_PARSE]);
84
    }
85
86
    /**
87
     * @deprecated
88
     * PHP error handler set by http://www.php.net/manual/en/function.set-error-handler.php
89
     *
90
     * Checks the PHP error and calls messageQuit() unless:
91
     *  - error_reporting() returns 0, or
92
     *  - the PHP error level is 0, or
93
     *  - the PHP error level is 8 (E_NOTICE) and stopOnNotice is false
94
     *
95
     * @param int $nr The PHP error level as per http://www.php.net/manual/en/errorfunc.constants.php
96
     * @param string $text Error message
97
     * @param string $file File where the error was detected
98
     * @param string $line Line number within $file
99
     * @return boolean
0 ignored issues
show
Documentation introduced by
Should the return type not be boolean|null?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
100
     */
101
    public function phpError($nr, $text, $file, $line)
102
    {
103
        if (error_reporting() == 0 || $nr == 0) {
104
            return true;
105
        }
106
        if ($this->container->stopOnNotice == false) {
107
            switch ($nr) {
108
                case E_NOTICE:
109
                    if ($this->container->error_reporting <= 2) {
110
                        return true;
111
                    }
112
                    $isError = false;
113
                    $msg = 'PHP Minor Problem (this message show logged in only)';
114
                    break;
115
                case E_STRICT:
116 View Code Duplication
                case E_DEPRECATED:
117
                    if ($this->container->error_reporting <= 1) {
118
                        return true;
119
                    }
120
                    $isError = true;
121
                    $msg = 'PHP Strict Standards Problem';
122
                    break;
123 View Code Duplication
                default:
124
                    if ($this->container->error_reporting === 0) {
125
                        return true;
126
                    }
127
                    $isError = true;
128
                    $msg = 'PHP Parse Error';
129
            }
130
        }
131
        if (is_readable($file)) {
132
            $source = file($file);
133
            $source = $this->container->getPhpCompat()->htmlspecialchars($source[$line - 1]);
134
        } else {
135
            $source = "";
136
        } //Error $nr in $file at $line: <div><code>$source</code></div>
137
138
        $this->messageQuit($msg, '', $isError, $nr, $file, $source, $text, $line);
0 ignored issues
show
Bug introduced by
The variable $msg does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
Bug introduced by
The variable $isError does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
139
    }
140
141
    /**
142
     * @param string $msg
143
     * @param string $query
144
     * @param bool $is_error
145
     * @param string $nr
146
     * @param string $file
147
     * @param string $source
148
     * @param string $text
149
     * @param string $line
150
     * @param string $output
151
     * @return bool
0 ignored issues
show
Documentation introduced by
Should the return type not be null|boolean?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
152
     */
153
    public function messageQuit(
154
        $msg = 'unspecified error',
155
        $query = '',
156
        $is_error = true,
157
        $nr = '',
158
        $file = '',
159
        $source = '',
160
        $text = '',
161
        $line = '',
162
        $output = '',
163
        $backtrace = array()
164
    ) {
165
        if (0 < $this->container->messageQuitCount) {
166
            return;
167
        }
168
        $this->container->messageQuitCount++;
169
        $MakeTable = $this->container->getService('makeTable');
170
        $MakeTable->setTableClass('grid');
171
        $MakeTable->setRowRegularClass('gridItem');
172
        $MakeTable->setRowAlternateClass('gridAltItem');
173
        $MakeTable->setColumnWidths(array('100px'));
174
175
        $table = array();
176
177
        $version = isset ($GLOBALS['modx_version']) ? $GLOBALS['modx_version'] : '';
178
        $release_date = isset ($GLOBALS['release_date']) ? $GLOBALS['release_date'] : '';
179
        $request_uri = "http://" . $_SERVER['HTTP_HOST'] . ($_SERVER["SERVER_PORT"] == 80 ? "" : (":" . $_SERVER["SERVER_PORT"])) . $_SERVER['REQUEST_URI'];
180
        $request_uri = $this->container->getPhpCompat()->htmlspecialchars($request_uri, ENT_QUOTES,
181
            $this->container->getConfig('modx_charset'));
182
        $ua = $this->container->getPhpCompat()->htmlspecialchars($_SERVER['HTTP_USER_AGENT'], ENT_QUOTES,
183
            $this->container->getConfig('modx_charset'));
184
        $referer = $this->container->getPhpCompat()->htmlspecialchars($_SERVER['HTTP_REFERER'], ENT_QUOTES,
185
            $this->container->getConfig('modx_charset'));
186
        if ($is_error) {
187
            $str = '<h2 style="color:red">&laquo; Evo Parse Error &raquo;</h2>';
188
            if ($msg != 'PHP Parse Error') {
189
                $str .= '<h3 style="color:red">' . $msg . '</h3>';
190
            }
191
        } else {
192
            $str = '<h2 style="color:#003399">&laquo; Evo Debug/ stop message &raquo;</h2>';
193
            $str .= '<h3 style="color:#003399">' . $msg . '</h3>';
194
        }
195
196
        if (!empty ($query)) {
197
            $str .= '<pre style="font-weight:bold;border:1px solid #ccc;padding:8px;color:#333;background-color:#ffffcd;margin-bottom:15px;">SQL &gt; <span id="sqlHolder">' . $query . '</span></pre>';
198
        }
199
200
        $errortype = array(
201
            E_ERROR             => "ERROR",
202
            E_WARNING           => "WARNING",
203
            E_PARSE             => "PARSING ERROR",
204
            E_NOTICE            => "NOTICE",
205
            E_CORE_ERROR        => "CORE ERROR",
206
            E_CORE_WARNING      => "CORE WARNING",
207
            E_COMPILE_ERROR     => "COMPILE ERROR",
208
            E_COMPILE_WARNING   => "COMPILE WARNING",
209
            E_USER_ERROR        => "USER ERROR",
210
            E_USER_WARNING      => "USER WARNING",
211
            E_USER_NOTICE       => "USER NOTICE",
212
            E_STRICT            => "STRICT NOTICE",
213
            E_RECOVERABLE_ERROR => "RECOVERABLE ERROR",
214
            E_DEPRECATED        => "DEPRECATED",
215
            E_USER_DEPRECATED   => "USER DEPRECATED"
216
        );
217
218
        if (!empty($nr) || !empty($file)) {
219
            if ($text != '') {
220
                $str .= '<pre style="font-weight:bold;border:1px solid #ccc;padding:8px;color:#333;background-color:#ffffcd;margin-bottom:15px;">Error : ' . $text . '</pre>';
221
            }
222
            if ($output != '') {
223
                $str .= '<pre style="font-weight:bold;border:1px solid #ccc;padding:8px;color:#333;background-color:#ffffcd;margin-bottom:15px;">' . $output . '</pre>';
224
            }
225
            if ($nr !== '') {
226
                $table[] = array('ErrorType[num]', $errortype [$nr] . "[" . $nr . "]");
227
            }
228
            if ($file) {
229
                $table[] = array('File', $file);
230
            }
231
            if ($line) {
232
                $table[] = array('Line', $line);
233
            }
234
235
        }
236
237
        if ($source != '') {
238
            $table[] = array("Source", $source);
239
        }
240
241
        if (!empty($this->currentSnippet)) {
242
            $table[] = array('Current Snippet', $this->currentSnippet);
0 ignored issues
show
Bug introduced by
The property currentSnippet does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
243
        }
244
245
        if (!empty($this->event->activePlugin)) {
246
            $table[] = array('Current Plugin', $this->event->activePlugin . '(' . $this->event->name . ')');
0 ignored issues
show
Bug introduced by
The property event does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
247
        }
248
249
        $str .= $MakeTable->create($table, array('Error information', ''));
250
        $str .= "<br />";
251
252
        $table = array();
253
        $table[] = array('REQUEST_URI', $request_uri);
254
255
        if ($this->container->getManagerApi()->action) {
256
            $actionName = Legacy\LogHandler::getAction($this->container->getManagerApi()->action);
257
            if (! empty($actionName)) {
258
                $actionName = ' - ' . $actionName;
259
            }
260
261
            $table[] = array('Manager action', $this->container->getManagerApi()->action . $actionName);
262
        }
263
264
        if (preg_match('@^[0-9]+@', $this->container->documentIdentifier)) {
265
            $resource = $this->container->getDocumentObject('id', $this->container->documentIdentifier);
266
            $url = $this->container->makeUrl($this->container->documentIdentifier, '', '', 'full');
267
            $table[] = array(
268
                'Resource',
269
                '[' . $this->container->documentIdentifier . '] <a href="' . $url . '" target="_blank">' . $resource['pagetitle'] . '</a>'
270
            );
271
        }
272
        $table[] = array('Referer', $referer);
273
        $table[] = array('User Agent', $ua);
274
        $table[] = array('IP', $_SERVER['REMOTE_ADDR']);
275
        $table[] = array(
276
            'Current time',
277
            date("Y-m-d H:i:s", $_SERVER['REQUEST_TIME'] + $this->container->getConfig('server_offset_time'))
278
        );
279
        $str .= $MakeTable->create($table, array('Basic info', ''));
280
        $str .= "<br />";
281
282
        $table = array();
283
        $table[] = array('MySQL', '[^qt^] ([^q^] Requests)');
284
        $table[] = array('PHP', '[^p^]');
285
        $table[] = array('Total', '[^t^]');
286
        $table[] = array('Memory', '[^m^]');
287
        $str .= $MakeTable->create($table, array('Benchmarks', ''));
288
        $str .= "<br />";
289
290
        $totalTime = ($this->container->getMicroTime() - $this->container->tstart);
291
292
        $mem = memory_get_peak_usage(true);
293
        $total_mem = $mem - $this->container->mstart;
294
        $total_mem = ($total_mem / 1024 / 1024) . ' mb';
295
296
        $queryTime = $this->container->queryTime;
297
        $phpTime = $totalTime - $queryTime;
298
        $queries = isset ($this->container->executedQueries) ? $this->container->executedQueries : 0;
299
        $queryTime = sprintf("%2.4f s", $queryTime);
300
        $totalTime = sprintf("%2.4f s", $totalTime);
301
        $phpTime = sprintf("%2.4f s", $phpTime);
302
303
        $str = str_replace('[^q^]', $queries, $str);
304
        $str = str_replace('[^qt^]', $queryTime, $str);
305
        $str = str_replace('[^p^]', $phpTime, $str);
306
        $str = str_replace('[^t^]', $totalTime, $str);
307
        $str = str_replace('[^m^]', $total_mem, $str);
308
309
        $php_errormsg = error_get_last();
310
        if (!empty($php_errormsg) && isset($php_errormsg['message'])) {
311
            $str = '<b>' . $php_errormsg['message'] . '</b><br />' . PHP_EOL . $str;
312
        }
313
        $str .= $this->getBacktrace(empty($backtrace) ? debug_backtrace() : $backtrace);
314
        // Log error
315
        if (!empty($this->container->currentSnippet)) {
316
            $source = 'Snippet - ' . $this->container->currentSnippet;
317
        } elseif (!empty($this->container->event->activePlugin)) {
318
            $source = 'Plugin - ' . $this->container->event->activePlugin;
319
        } elseif ($source !== '') {
320
            $source = 'Parser - ' . $source;
321
        } elseif ($query !== '') {
322
            $source = 'SQL Query';
323
        } else {
324
            $source = 'Parser';
325
        }
326
        if ($msg) {
327
            $source .= ' / ' . $msg;
328
        }
329
        if (isset($actionName) && !empty($actionName)) {
330
            $source .= $actionName;
331
        }
332 View Code Duplication
        switch ($nr) {
333
            case E_DEPRECATED :
334
            case E_USER_DEPRECATED :
335
            case E_STRICT :
336
            case E_NOTICE :
337
            case E_USER_NOTICE :
338
                $error_level = 2;
339
                break;
340
            default:
341
                $error_level = 3;
342
        }
343
344
        if ($this->container->getDatabase()->getDriver()->isConnected()) {
345
            $this->container->logEvent(0, $error_level, $str, $source);
346
        }
347
348
        if ($error_level === 2 && $this->container->error_reporting !== '99') {
349
            return true;
350
        }
351
        if ($this->container->error_reporting === '99' && !isset($_SESSION['mgrValidated'])) {
352
            return true;
353
        }
354
        if (!headers_sent()) {
355
            // Set 500 response header
356
            if ($error_level !== 2) {
357
                header('HTTP/1.1 500 Internal Server Error');
358
            }
359
            ob_get_clean();
360
        }
361
362
        // Display error
363
        if ($this->shouldDisplay()) {
364
            echo '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"><html><head><title>EVO Content Manager ' . $version . ' &raquo; ' . $release_date . '</title>
365
                 <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
366
                 <link rel="stylesheet" type="text/css" href="' . MODX_MANAGER_URL . 'media/style/' . $this->container->getConfig('manager_theme',
367
                    'default') . '/style.css" />
368
                 <style type="text/css">body { padding:10px; } td {font:inherit;}</style>
369
                 </head><body>
370
                 ' . $str . '</body></html>';
371
372
        } else {
373
            echo 'Error';
374
        }
375
        ob_end_flush();
376
        exit;
377
    }
378
379
    protected function shouldDisplay()
380
    {
381
        return isset($_SESSION['mgrValidated']) || $this->container['config']->get('app.debug');
382
    }
383
384
    /**
385
     * @param $backtrace
386
     * @return string
387
     */
388
    public function getBacktrace($backtrace)
389
    {
390
        $MakeTable = $this->container->getService('makeTable');
391
        $MakeTable->setTableClass('grid');
392
        $MakeTable->setRowRegularClass('gridItem');
393
        $MakeTable->setRowAlternateClass('gridAltItem');
394
        $table = array();
395
        $backtrace = array_reverse($backtrace);
396
        foreach ($backtrace as $key => $val) {
397
            $key++;
398
            if (substr($val['function'], 0, 11) === 'messageQuit') {
399
                break;
400
            } elseif (substr($val['function'], 0, 8) === 'phpError') {
401
                break;
402
            }
403
            $path = str_replace('\\', '/', $val['file']);
404
            if (strpos($path, MODX_BASE_PATH) === 0) {
405
                $path = substr($path, strlen(MODX_BASE_PATH));
406
            }
407
            switch (get_by_key($val, 'type')) {
408
                case '->':
409
                case '::':
410
                    $functionName = $val['function'] = $val['class'] . $val['type'] . $val['function'];
411
                    break;
412
                default:
413
                    $functionName = $val['function'];
414
            }
415
            $tmp = 1;
416
            $_ = (!empty($val['args'])) ? count($val['args']) : 0;
417
            $args = array_pad(array(), $_, '$var');
418
            $args = implode(", ", $args);
419
            $modx = &$this;
420
            $args = preg_replace_callback('/\$var/', function () use ($modx, &$tmp, $val) {
421
                $arg = $val['args'][$tmp - 1];
422
                switch (true) {
423
                    case is_null($arg):
424
                        {
425
                            $out = 'NULL';
426
                            break;
427
                        }
428
                    case is_numeric($arg):
429
                        {
430
                            $out = $arg;
431
                            break;
432
                        }
433
                    case is_scalar($arg):
434
                        {
435
                            $out = strlen($arg) > 20 ? 'string $var' . $tmp : ("'" . $this->container->getPhpCompat()->htmlspecialchars(str_replace("'",
436
                                    "\\'", $arg)) . "'");
437
                            break;
438
                        }
439
                    case is_bool($arg):
440
                        {
441
                            $out = $arg ? 'TRUE' : 'FALSE';
442
                            break;
443
                        }
444
                    case is_array($arg):
445
                        {
446
                            $out = 'array $var' . $tmp;
447
                            break;
448
                        }
449
                    case is_object($arg):
450
                        {
451
                            $out = get_class($arg) . ' $var' . $tmp;
452
                            break;
453
                        }
454
                    default:
455
                        {
456
                            $out = '$var' . $tmp;
457
                        }
458
                }
459
                $tmp++;
460
461
                return $out;
462
            }, $args);
463
            $line = array(
464
                "<strong>" . $functionName . "</strong>(" . $args . ")",
465
                $path . " on line " . $val['line']
466
            );
467
            $table[] = array(implode("<br />", $line));
468
        }
469
470
        return $MakeTable->create($table, array('Backtrace'));
471
    }
472
473
    /**
474
     * Determine if the exception should be reported.
475
     *
476
     * @param  \Throwable $exception
477
     * @return bool
478
     */
479
    public function shouldReport(\Throwable $exception)
0 ignored issues
show
Unused Code introduced by
The parameter $exception is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
480
    {
481
        return true;
482
    }
483
484
    /**
485
     * @deprecated
486
     * @param \Throwable $exception
487
     */
488
    public function handleException(\Throwable $exception)
489
    {
490
        if (!$exception instanceof Exception) {
491
            $exception = new FatalThrowableError($exception);
492
        }
493
494
        if (
495
            $exception instanceof ConnectException ||
496
            ($exception instanceof \PDOException && $exception->getCode() === 1045)
497
        ) {
498
            $this->container->getDatabase()->disconnect();
499
        }
500
501
        $this->messageQuit(
502
            $exception->getMessage(),
0 ignored issues
show
Bug introduced by
The method getMessage does only exist in Exception, but not in Symfony\Component\Debug\...ion\FatalThrowableError.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
503
            '',
504
            true,
505
            '',
506
            $exception->getFile(),
0 ignored issues
show
Bug introduced by
The method getFile does only exist in Exception, but not in Symfony\Component\Debug\...ion\FatalThrowableError.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
507
            '',
508
            '',
509
            $exception->getLine(),
0 ignored issues
show
Bug introduced by
The method getLine does only exist in Exception, but not in Symfony\Component\Debug\...ion\FatalThrowableError.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
510
            '',
511
            $exception->getTrace()
0 ignored issues
show
Bug introduced by
The method getTrace does only exist in Exception, but not in Symfony\Component\Debug\...ion\FatalThrowableError.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
512
        );
513
    }
514
}
515