Completed
Push — master ( 5467e4...183ea4 )
by Boy
05:06 queued 01:02
created

ExceptionListener::onKernelException()   C

Complexity

Conditions 7
Paths 9

Size

Total Lines 22
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 22
rs 6.9811
cc 7
eloc 15
nc 9
nop 1
1
<?php
2
3
/**
4
 * Copyright 2014 SURFnet bv
5
 *
6
 * Licensed under the Apache License, Version 2.0 (the "License");
7
 * you may not use this file except in compliance with the License.
8
 * You may obtain a copy of the License at
9
 *
10
 *     http://www.apache.org/licenses/LICENSE-2.0
11
 *
12
 * Unless required by applicable law or agreed to in writing, software
13
 * distributed under the License is distributed on an "AS IS" BASIS,
14
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
 * See the License for the specific language governing permissions and
16
 * limitations under the License.
17
 */
18
19
namespace Surfnet\StepupMiddleware\ApiBundle\EventListener;
20
21
use Broadway\Repository\AggregateNotFoundException;
22
use Exception;
23
use Psr\Log\LoggerInterface;
24
use Surfnet\Stepup\Exception\DomainException;
25
use Surfnet\StepupMiddleware\ApiBundle\Exception\BadApiRequestException;
26
use Surfnet\StepupMiddleware\ApiBundle\Exception\BadCommandRequestException;
27
use Surfnet\StepupMiddleware\CommandHandlingBundle\Pipeline\Exception\InvalidCommandException;
28
use Symfony\Component\HttpFoundation\JsonResponse;
29
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
30
use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
31
32
/**
33
 * Converts all exceptions into JSON responses.
34
 */
35
class ExceptionListener
36
{
37
    /**
38
     * @var LoggerInterface
39
     */
40
    private $logger;
41
42
    public function __construct(LoggerInterface $logger)
43
    {
44
        $this->logger = $logger;
45
    }
46
47
    public function onKernelException(GetResponseForExceptionEvent $event)
48
    {
49
        $exception = $event->getException();
50
51
        $this->logException($exception);
52
53
        if ($exception instanceof HttpExceptionInterface && $exception instanceof Exception) {
54
            $statusCode = $exception->getStatusCode();
55
            $headers = $exception->getHeaders();
56
        } else {
57
            $statusCode = $exception instanceof BadApiRequestException
58
                    || $exception instanceof BadCommandRequestException
59
                    || $exception instanceof DomainException
60
                    || $exception instanceof AggregateNotFoundException
61
                ? 400
62
                : 500;
63
64
            $headers = [];
65
        }
66
67
        $event->setResponse($this->createJsonErrorResponse($exception, $statusCode, $headers));
68
    }
69
70
    private function logException(Exception $exception)
71
    {
72
        # As per \Symfony\Component\HttpKernel\EventListener\ExceptionListener#logException().
0 ignored issues
show
Coding Style introduced by
Perl-style comments are not allowed. Use "// Comment." or "/* comment */" instead.
Loading history...
73
        $isCritical = !$exception instanceof HttpExceptionInterface || $exception->getStatusCode() >= 500;
74
75
        if ($isCritical) {
76
            $this->logger->critical($exception->getMessage(), ['exception' => $exception]);
77
        } else {
78
            $this->logger->error($exception->getMessage(), ['exception' => $exception]);
79
        }
80
    }
81
82
    /**
83
     * @param Exception $exception
84
     * @param int $statusCode
85
     * @param array $headers OPTIONAL
86
     * @return JsonResponse
87
     */
88
    private function createJsonErrorResponse(Exception $exception, $statusCode, $headers = [])
89
    {
90
        if ($exception instanceof BadApiRequestException
91
            || $exception instanceof BadCommandRequestException
92
            || $exception instanceof InvalidCommandException
93
        ) {
94
            $errors = $exception->getErrors();
95
        } else {
96
            $errors = [sprintf('%s: %s', get_class($exception), $exception->getMessage())];
97
        }
98
99
        return new JsonResponse(['errors' => $errors], $statusCode, $headers);
100
    }
101
}
102