Completed
Pull Request — master (#49)
by John
02:41
created

ExceptionListener::onKernelException()   C

Complexity

Conditions 11
Paths 181

Size

Total Lines 65
Code Lines 53

Duplication

Lines 0
Ratio 0 %

Importance

Changes 6
Bugs 0 Features 0
Metric Value
c 6
b 0
f 0
dl 0
loc 65
rs 5.5833
cc 11
eloc 53
nc 181
nop 1

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/*
3
 * This file is part of the KleijnWeb\SwaggerBundle package.
4
 *
5
 * For the full copyright and license information, please view the LICENSE
6
 * file that was distributed with this source code.
7
 */
8
9
namespace KleijnWeb\SwaggerBundle\EventListener;
10
11
use KleijnWeb\SwaggerBundle\Exception\InvalidParametersException;
12
use KleijnWeb\SwaggerBundle\Response\VndValidationErrorFactory;
13
use KleijnWeb\SwaggerBundle\Response\VndErrorResponse;
14
use Psr\Log\LoggerInterface;
15
use Psr\Log\LogLevel;
16
use Ramsey\VndError\VndError;
17
use Symfony\Component\HttpFoundation\Request;
18
use Symfony\Component\HttpFoundation\Response;
19
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
20
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
21
use Symfony\Component\Security\Core\Exception\AuthenticationException;
22
23
/**
24
 * @author John Kleijn <[email protected]>
25
 */
26
class ExceptionListener
27
{
28
    /**
29
     * @var LoggerInterface
30
     */
31
    private $logger;
32
33
    /**
34
     * @var VndValidationErrorFactory
35
     */
36
    private $validationErrorFactory;
37
38
    /**
39
     * @param VndValidationErrorFactory $errorFactory
40
     * @param LoggerInterface           $logger
41
     */
42
    public function __construct(VndValidationErrorFactory $errorFactory, LoggerInterface $logger)
43
    {
44
        $this->logger = $logger;
45
        $this->validationErrorFactory = $errorFactory;
46
    }
47
48
    /**
49
     * @param LoggerInterface $logger
50
     *
51
     * @return $this
52
     */
53
    public function setLogger(LoggerInterface $logger)
54
    {
55
        $this->logger = $logger;
56
57
        return $this;
58
    }
59
60
    /**
61
     * @param GetResponseForExceptionEvent $event
62
     *
63
     * @throws \Exception
64
     */
65
    public function onKernelException(GetResponseForExceptionEvent $event)
66
    {
67
        $logRef = uniqid();
68
69
        try {
70
            $exception = $event->getException();
71
            $request = $event->getRequest();
72
            $code = $exception->getCode();
73
74
            if ($exception instanceof InvalidParametersException) {
75
                $severity = LogLevel::NOTICE;
76
                $statusCode = Response::HTTP_BAD_REQUEST;
77
                $vndError = $this->validationErrorFactory->create($request, $exception, $logRef);
78
            } else {
79
                if ($exception instanceof NotFoundHttpException) {
80
                    $statusCode = Response::HTTP_NOT_FOUND;
81
                    $severity = LogLevel::INFO;
82
                } else {
83
                    if ($exception instanceof AuthenticationException) {
84
                        $statusCode = Response::HTTP_UNAUTHORIZED;
85
                        $severity = LogLevel::WARNING;
86
                    } else {
87
                        $is3Digits = strlen($code) === 3;
88
                        $class = (int)substr($code, 0, 1);
89
                        if (!$is3Digits) {
90
                            $statusCode = Response::HTTP_INTERNAL_SERVER_ERROR;
91
                            $severity = LogLevel::CRITICAL;
92
                        } else {
93
                            switch ($class) {
94
                                case 4:
95
                                    $severity = LogLevel::NOTICE;
96
                                    $statusCode = Response::HTTP_BAD_REQUEST;
97
                                    break;
98
                                case 5:
99
                                    $statusCode = Response::HTTP_INTERNAL_SERVER_ERROR;
100
                                    $severity = LogLevel::ERROR;
101
                                    break;
102
                                default:
103
                                    $statusCode = Response::HTTP_INTERNAL_SERVER_ERROR;
104
                                    $severity = LogLevel::CRITICAL;
105
                            }
106
                        }
107
                    }
108
                }
109
                $message = Response::$statusTexts[$statusCode];
110
                $vndError = new VndError($message, $logRef);
111
                $vndError->addLink('help', $request->get('_resource'), ['title' => 'Error Information']);
112
                $vndError->addLink('about', $request->getUri(), ['title' => 'Error Information']);
113
            }
114
115
            $reference = $logRef ? " [logref $logRef]" : '';
116
            $event->setResponse(new VndErrorResponse($vndError, $statusCode));
117
            $this->logger->log($severity, "{$vndError->getMessage()}{$reference}: $exception");
118
        } catch (\PHPUnit_Framework_Exception  $e) {
119
            throw $e;
120
        } catch (\PHPUnit_Framework_Error  $e) {
121
            throw $e;
122
        } catch (\Exception $e) {
123
            // A simpler response where less can go wrong
124
            $message = "Error Handling Failure";
125
            $vndError = new VndError($message, $logRef);
126
            $this->logger->log(LogLevel::CRITICAL, "$message [logref $logRef]: $e");
127
            $event->setResponse(new VndErrorResponse($vndError, Response::HTTP_INTERNAL_SERVER_ERROR));
128
        }
129
    }
130
}
131