Passed
Push — master ( 91f02d...65071d )
by Melech
21:33 queued 07:21
created

ExceptionHandler   A

Complexity

Total Complexity 4

Size/Duplication

Total Lines 68
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 4
eloc 15
dl 0
loc 68
rs 10
c 0
b 0
f 0

2 Methods

Rating   Name   Duplication   Size   Complexity  
A getTraceCode() 0 4 1
A enable() 0 38 3
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the Valkyrja Framework package.
7
 *
8
 * (c) Melech Mizrachi <[email protected]>
9
 *
10
 * For the full copyright and license information, please view the LICENSE
11
 * file that was distributed with this source code.
12
 */
13
14
namespace Valkyrja\Exception;
15
16
use Override;
0 ignored issues
show
Bug introduced by
The type Override was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
17
use Throwable;
0 ignored issues
show
Bug introduced by
This use statement conflicts with another class in this namespace, Valkyrja\Exception\Throwable. Consider defining an alias.

Let?s assume that you have a directory layout like this:

.
|-- OtherDir
|   |-- Bar.php
|   `-- Foo.php
`-- SomeDir
    `-- Foo.php

and let?s assume the following content of Bar.php:

// Bar.php
namespace OtherDir;

use SomeDir\Foo; // This now conflicts the class OtherDir\Foo

If both files OtherDir/Foo.php and SomeDir/Foo.php are loaded in the same runtime, you will see a PHP error such as the following:

PHP Fatal error:  Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php

However, as OtherDir/Foo.php does not necessarily have to be loaded and the error is only triggered if it is loaded before OtherDir/Bar.php, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias:

// Bar.php
namespace OtherDir;

use SomeDir\Foo as SomeDirFoo; // There is no conflict anymore.
Loading history...
18
use Valkyrja\Exception\Contract\ExceptionHandler as Contract;
19
use Whoops\Handler\JsonResponseHandler;
20
use Whoops\Handler\PrettyPageHandler;
21
use Whoops\Run;
22
use Whoops\Util\Misc;
23
24
use const E_ALL;
25
26
/**
27
 * Class ExceptionHandler.
28
 *
29
 * @author Melech Mizrachi
30
 */
31
class ExceptionHandler implements Contract
32
{
33
    /**
34
     * Whether debug is enabled or not.
35
     *
36
     * @var bool
37
     */
38
    public static bool $enabled = false;
39
40
    /**
41
     * Enable debug mode.
42
     *
43
     * @param int  $errorReportingLevel [optional] The error reporting level
44
     * @param bool $displayErrors       [optional] Whether to display errors
45
     *
46
     * @return void
47
     */
48
    #[Override]
49
    public static function enable(int $errorReportingLevel = E_ALL, bool $displayErrors = false): void
50
    {
51
        // If debug is already enabled
52
        if (static::$enabled) {
53
            // Don't do things twice
54
            return;
55
        }
56
57
        // Debug is enabled
58
        static::$enabled = true;
59
60
        $run = new Run();
61
62
        // We want the error page to be shown by default, if this is a
63
        // regular request, so that's the first thing to go into the stack:
64
        $run->pushHandler(new PrettyPageHandler());
65
66
        // Now, we want a second handler that will run before the error page,
67
        // and immediately return an error message in JSON format, if something
68
        // goes awry.
69
        if (Misc::isAjaxRequest()) {
70
            $jsonHandler = new JsonResponseHandler();
71
72
            // You can also tell JsonResponseHandler to give you a full stack trace:
73
            // $jsonHandler->addTraceToOutput(true);
74
75
            // You can also return a result compliant to the json:api spec
76
            // re: http://jsonapi.org/examples/#error-objects
77
            // tl;dr: error[] becomes errors[[]]
78
            $jsonHandler->setJsonApi(true);
79
80
            // And push it into the stack:
81
            $run->pushHandler($jsonHandler);
82
        }
83
84
        // That's it! Register Whoops and throw a dummy exception:
85
        $run->register();
86
    }
87
88
    /**
89
     * Get trace code for a throwable/exception.
90
     *
91
     * @param Throwable $exception The exception/throwable
92
     *
93
     * @return string
94
     */
95
    #[Override]
96
    public static function getTraceCode(Throwable $exception): string
97
    {
98
        return md5($exception->getTraceAsString());
99
    }
100
}
101