Completed
Push — master ( 9561ee...bb752b )
by Dawid
02:42
created

ErrorMiddleware::restoreErrorHandler()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php declare(strict_types=1);
2
3
namespace Igni\Http\Middleware;
4
5
use Igni\Http\Exception\HttpException;
6
use Igni\Http\Response;
7
use Psr\Http\Message\ResponseInterface;
8
use Psr\Http\Message\ServerRequestInterface;
9
use Psr\Http\Server\MiddlewareInterface;
10
use Psr\Http\Server\RequestHandlerInterface;
11
use Throwable;
12
use ErrorException;
13
14
/**
15
 * Middleware for error handling. If an exception is thrown and not catch during the request cycle,
16
 * it will appear here. Middleware will catch it and return response with status code (500) and exception message
17
 * as a body.
18
 *
19
 * @package Igni\Http\Middleware
20
 */
21
final class ErrorMiddleware implements MiddlewareInterface
22
{
23
    private $errorHandler;
24
25
    /**
26
     * ErrorMiddleware constructor.
27
     *
28
     * @param callable $errorHandler
29
     */
30 14
    public function __construct(callable $errorHandler)
31
    {
32 14
        $this->errorHandler = $errorHandler;
33 14
    }
34
35
    /**
36
     * @see MiddlewareInterface::process
37
     *
38
     * @param ServerRequestInterface $request
39
     * @param RequestHandlerInterface $next
40
     * @return ResponseInterface
41
     */
42 13
    public function process(ServerRequestInterface $request, RequestHandlerInterface $next): ResponseInterface
43
    {
44 13
        $this->setErrorHandler();
45
46
        try {
47 13
            $response = $next->handle($request);
48
49 4
        } catch (Throwable $exception) {
50 4
            ($this->errorHandler)($exception);
51
52 4
            if ($exception instanceof HttpException) {
53 2
                $response = Response::fromText($exception->getHttpBody(), $exception->getHttpStatusCode());
54
            } else {
55 2
                $response = Response::fromText((string) $exception, Response::HTTP_INTERNAL_SERVER_ERROR);
56
            }
57
58
        }
59
60 13
        $this->restoreErrorHandler();
61
62 13
        return $response;
63
    }
64
65
66 13
    private function setErrorHandler(): void
67
    {
68
        set_error_handler(function (int $number, string $message, string $file, int $line) {
69
70 1
            if (!(error_reporting() & $number)) {
71
                return;
72
            }
73
74 1
            throw new ErrorException($message, 0, $number, $file, $line);
75 13
        });
76 13
    }
77
78 13
    private function restoreErrorHandler(): void
79
    {
80 13
        restore_error_handler();
81 13
    }
82
}
83