Completed
Pull Request — master (#1)
by Woody
27:07 queued 01:07
created

ExceptionHandler::__invoke()   B

Complexity

Conditions 4
Paths 5

Size

Total Lines 34
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 0
loc 34
rs 8.5806
cc 4
eloc 21
nc 5
nop 3
1
<?php
2
3
namespace Equip\Handler;
4
5
use Exception;
6
use InvalidArgumentException;
7
use Negotiation\Negotiator;
8
use Psr\Http\Message\ResponseInterface;
9
use Psr\Http\Message\ServerRequestInterface;
10
use Relay\ResolverInterface;
11
use Equip\Exception\HttpException;
12
use Whoops\Run as Whoops;
13
14
class ExceptionHandler
15
{
16
    /**
17
     * @var Negotiator
18
     */
19
    private $negotiator;
20
21
    /**
22
     * @var ExceptionHandlerPreferences
23
     */
24
    private $preferences;
25
26
    /**
27
     * @var ResolverInterface
28
     */
29
    private $resolver;
30
31
    /**
32
     * @var Whoops
33
     */
34
    private $whoops;
35
36
    /**
37
     * @param ExceptionHandlerPreferences $preferences
38
     * @param Negotiator $negotiator
39
     * @param ResolverInterface $resolver
40
     * @param Whoops $whoops
41
     */
42 12
    public function __construct(
43
        ExceptionHandlerPreferences $preferences,
44
        Negotiator $negotiator,
45
        ResolverInterface $resolver,
46
        Whoops $whoops
47
    ) {
48 12
        $this->preferences = $preferences;
49 12
        $this->negotiator = $negotiator;
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 2 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
50 12
        $this->resolver = $resolver;
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 4 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
51 12
        $this->whoops = $whoops;
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 6 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
52 12
    }
53
54
    /**
55
     * @param ServerRequestInterface $request
56
     * @param ResponseInterface $response
57
     * @param callable $next
58
     *
59
     * @return ResponseInterface
60
     */
61 12
    public function __invoke(
62
        ServerRequestInterface $request,
63
        ResponseInterface $response,
64
        callable $next
65
    ) {
66
        try {
67 12
            return $next($request, $response);
68 12
        } catch (Exception $e) {
69 12
            $type = $this->type($request);
70
71 12
            $response = $response->withHeader('Content-Type', $type);
72
73
            try {
74 12
                $response = $response->withStatus($e->getCode());
75 10
            } catch (InvalidArgumentException $_) {
76
                // Exception did not contain a valid code
77 10
                $response = $response->withStatus(500);
78
            }
79
80 12
            if ($e instanceof HttpException) {
81 2
                $response = $e->withResponse($response);
82
            }
83
84 12
            $handler = $this->handler($type);
85 12
            $this->whoops->pushHandler($handler);
0 ignored issues
show
Documentation introduced by
$handler is of type object<Whoops\Handler\HandlerInterface>, but the function expects a callable.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
86
87 12
            $body = $this->whoops->handleException($e);
88 12
            $response->getBody()->write($body);
89
90 12
            $this->whoops->popHandler();
91
92 12
            return $response;
93
        }
94
    }
95
96
    /**
97
     * Determine the preferred content type for the current request
98
     *
99
     * @param ServerRequestInterface $request
100
     *
101
     * @return string
102
     */
103 12
    private function type(ServerRequestInterface $request)
104
    {
105 12
        $accept = $request->getHeaderLine('Accept');
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 5 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
106 12
        $priorities = $this->preferences->toArray();
107
108 12
        if (!empty($accept)) {
109 10
            $preferred = $this->negotiator->getBest($accept, array_keys($priorities));
110
        }
111
112 12
        if (!empty($preferred)) {
113 10
            return $preferred->getValue();
114
        }
115
116 2
        return key($priorities);
117
    }
118
119
    /**
120
     * Retrieve the handler to use for the given type
121
     *
122
     * @param string $type
123
     *
124
     * @return \Whoops\Handler\HandlerInterface
125
     */
126 12
    private function handler($type)
127
    {
128 12
        return call_user_func($this->resolver, $this->preferences[$type]);
129
    }
130
}
131