Completed
Push — master ( ca1131...42ef77 )
by Woody
03:33
created

src/Handler/ExceptionHandler.php (1 issue)

Severity

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

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;
50 12
        $this->resolver = $resolver;
51 12
        $this->whoops = $whoops;
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 12
            } 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 2
            }
83
84 12
            $handler = $this->handler($type);
85 12
            $this->whoops->pushHandler($handler);
86
87 12
            $body = $this->whoops->handleException($e);
0 ignored issues
show
$e is of type object<Exception>, but the function expects a object<Throwable>.

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...
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');
106 12
        $priorities = $this->preferences->toArray();
107
108 12
        if (!empty($accept)) {
109 10
            $preferred = $this->negotiator->getBest($accept, array_keys($priorities));
110 10
        }
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