Passed
Push — main ( 13bcd8...97d8ea )
by Chema
54s queued 14s
created

Router::handleException()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 15
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 3.0175

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 7
nc 3
nop 2
dl 0
loc 15
ccs 7
cts 8
cp 0.875
crap 3.0175
rs 10
c 1
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Gacela\Router;
6
7
use Closure;
8
use Exception;
9
use Gacela\Resolver\InstanceCreator;
10
use Gacela\Router\Entities\Route;
11
use Gacela\Router\Exceptions\NotFound404Exception;
12
use ReflectionException;
13
use ReflectionFunction;
14
15
use function get_class;
16
use function is_callable;
17
18
final class Router
19
{
20
    /**
21
     * @throws ReflectionException
22
     */
23 82
    public static function configure(Closure $fn): void
24
    {
25 82
        $routes = new Routes();
26 82
        $bindings = new Bindings();
27 82
        $handlers = new Handlers();
28
29 82
        $params = array_map(static fn ($param) => match ((string)$param->getType()) {
30 82
            Routes::class => $routes,
31 82
            Bindings::class => $bindings,
32 82
            Handlers::class => $handlers,
33 82
            default => null,
34 82
        }, (new ReflectionFunction($fn))->getParameters());
35
36 82
        $fn(...$params);
37
38
        try {
39 81
            echo self::findRoute($routes)
40 81
                ->run($bindings);
41 11
        } catch (Exception $exception) {
42 11
            echo self::handleException($handlers, $exception);
43
        }
44
    }
45
46 81
    private static function findRoute(Routes $routes): Route
47
    {
48 81
        foreach ($routes->getAllRoutes() as $route) {
49 79
            if ($route->requestMatches()) {
50 74
                return $route;
51
            }
52
        }
53
54 7
        throw new NotFound404Exception();
55
    }
56
57 11
    private static function handleException(Handlers $handlers, Exception $exception): string
58
    {
59 11
        $handler = self::findHandler($handlers, $exception);
60
61 11
        if (is_callable($handler)) {
62 4
            return $handler($exception);
63
        }
64
65 7
        $instance = (new InstanceCreator())->createByClassName($handler);
0 ignored issues
show
Bug introduced by
It seems like $handler can also be of type callable; however, parameter $className of Gacela\Resolver\Instance...or::createByClassName() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

65
        $instance = (new InstanceCreator())->createByClassName(/** @scrutinizer ignore-type */ $handler);
Loading history...
66
67 7
        if (is_callable($instance)) {
68 7
            return $instance($exception);
69
        }
70
71
        return '';
72
    }
73
74
    /**
75
     * @return callable|class-string
0 ignored issues
show
Documentation Bug introduced by
The doc comment callable|class-string at position 2 could not be parsed: Unknown type name 'class-string' at position 2 in callable|class-string.
Loading history...
76
     */
77 11
    private static function findHandler(Handlers $handlers, Exception $exception): string|callable
78
    {
79 11
        return $handlers->getAllHandlers()[get_class($exception)]
80 11
            ?? $handlers->getAllHandlers()[Exception::class];
81
    }
82
}
83