Completed
Push — master ( 80cb77...df0c5b )
by Philip
06:12
created

KernelExceptionListener   A

Complexity

Total Complexity 15

Size/Duplication

Total Lines 102
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Test Coverage

Coverage 85.71%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 15
lcom 1
cbo 3
dl 0
loc 102
ccs 36
cts 42
cp 0.8571
rs 10
c 1
b 0
f 0

6 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
B onKernelException() 0 31 4
A isInterceptionPath() 0 14 4
A isDebug() 0 4 1
A setDebug() 0 4 1
A resolveStatusCode() 0 16 4
1
<?php
2
3
namespace Dontdrinkandroot\RestBundle\Listener;
4
5
use Doctrine\ORM\OptimisticLockException;
6
use Symfony\Component\HttpFoundation\JsonResponse;
7
use Symfony\Component\HttpFoundation\Request;
8
use Symfony\Component\HttpFoundation\Response;
9
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
10
use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
11
use Symfony\Component\Security\Core\Exception\BadCredentialsException;
12
use Symfony\Component\Security\Core\Exception\InsufficientAuthenticationException;
13
14
/**
15
 * @author Philip Washington Sorst <[email protected]>
16
 */
17
class KernelExceptionListener
18
{
19
    /**
20
     * @var string[]
21
     */
22
    private $paths;
23
24
    /**
25
     * @var bool
26
     */
27
    private $debug = false;
28
29 96
    public function __construct(array $paths)
30
    {
31 96
        $this->paths = $paths;
32 96
    }
33
34 12
    public function onKernelException(GetResponseForExceptionEvent $event)
35
    {
36 12
        $exception = $event->getException();
37 12
        $request = $event->getRequest();
38 12
        if (!$this->isInterceptionPath($request)) {
39 8
            return;
40
        }
41
42 4
        $data = null;
43 4
        if ($this->debug) {
44
            $data = [
45 4
                'class'   => get_class($exception),
46 4
                'message' => $exception->getMessage(),
47 4
                'trace'   => $exception->getTrace()
48
            ];
49
        }
50
51 4
        $statusCode = $this->resolveStatusCode($exception);
52
53 4
        $response = new JsonResponse($data);
54
55 4
        if ($exception instanceof HttpExceptionInterface) {
56 4
            $statusCode = $exception->getStatusCode();
57 4
            $response->setStatusCode($exception->getStatusCode());
58 4
            $response->headers->add($exception->getHeaders());
59
        }
60
61 4
        $response->setStatusCode($statusCode);
62
63 4
        $event->setResponse($response);
64 4
    }
65
66 12
    private function isInterceptionPath(?Request $request): bool
67
    {
68 12
        if (null === $request) {
69
            return false;
70
        }
71
72 12
        foreach ($this->paths as $path) {
73 4
            if (0 === strpos($request->getPathInfo(), $path)) {
74 4
                return true;
75
            }
76
        }
77
78 8
        return false;
79
    }
80
81
    /**
82
     * @return bool
83
     */
84
    public function isDebug(): bool
85
    {
86
        return $this->debug;
87
    }
88
89
    /**
90
     * @param bool $debug
91
     */
92 96
    public function setDebug(bool $debug)
93
    {
94 96
        $this->debug = $debug;
95 96
    }
96
97
    /**
98
     * @param $exception
99
     *
100
     * @return int
101
     */
102 4
    protected function resolveStatusCode($exception): int
103
    {
104 4
        if ($exception instanceof InsufficientAuthenticationException) {
105
            return Response::HTTP_UNAUTHORIZED;
106
        }
107
108 4
        if ($exception instanceof BadCredentialsException) {
109
            return Response::HTTP_UNAUTHORIZED;
110
        }
111
112 4
        if ($exception instanceof OptimisticLockException) {
113
            return Response::HTTP_PRECONDITION_FAILED;
114
        }
115
116 4
        return Response::HTTP_INTERNAL_SERVER_ERROR;
117
    }
118
}
119