Passed
Branch master (267be1)
by Eugene
03:26
created

ErrorHandler::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 4
ccs 0
cts 3
cp 0
rs 10
cc 1
eloc 2
nc 1
nop 1
crap 2
1
<?php
2
namespace Staticus\Middlewares;
3
4
use Psr\Http\Message\ServerRequestInterface as Request;
5
use Psr\Http\Message\ResponseInterface as Response;
6
use Staticus\Config\ConfigInterface;
7
use Staticus\Config\Config;
8
use Staticus\Diactoros\Response\NotFoundResponse;
9
use Staticus\Exceptions\ExceptionCodes;
10
use Staticus\Exceptions\ResourceNotFoundException;
11
use Staticus\Exceptions\WrongRequestException;
12
use Staticus\Resources\ResourceDOInterface;
13
use Zend\Diactoros\Response\JsonResponse;
14
15
class ErrorHandler
16
{
17
    /**
18
     * @var ConfigInterface|Config
19
     */
20
    private $config;
21
22
    public function __construct(ConfigInterface $config)
23
    {
24
        $this->config = $config;
25
    }
26
27
    public function __invoke($error, Request $request, Response $response, callable $next)
28
    {
29
        /*
30
         If $error is not an exception, it will use the response status if it already indicates an error
31
         (ie., >= 400 status), or will use a 500 status, and return the response directly with the reason phrase.
32
         */
33
        if ($error instanceof \Exception) {
34
            $className = $error->getTrace();
35
            if (isset($className[0]['class'])) {
36
                $className = $className[0]['class'];
37
            }
38
            if ($error instanceof ResourceNotFoundException) {
39
                $error = $this->getErrorArray($error->getMessage(), $this->getErrorCode($error, $className), $error->getResourceDO());
40
41
                return new NotFoundResponse($error);
42
            } else if ($error instanceof WrongRequestException) {
43
44
                /** @see \Zend\Diactoros\Response::$phrases */
45
                return $this->response(400, $error->getMessage(),
46
                    ExceptionCodes::code($className) . '.' . $error->getCode());
47
            } else {
48
49
                $message = $this->config->get('error_handler', false)
50
                    ? $error->getMessage()
51
                    : 'Internal error';
52
53
                /** @see \Zend\Diactoros\Response::$phrases */
54
                return $this->response(503, $message, $this->getErrorCode($error, $className));
55
            }
56
        } else {
57
            $next($request, $response, $next);
58
        }
59
    }
60
    protected function response($status, $message, $code)
61
    {
62
        $error = $this->getErrorArray($message, $code);
63
64
        return new JsonResponse($error, $status);
65
    }
66
67
    /**
68
     * @param $message
69
     * @param $code
70
     * @param ResourceDOInterface $resourceDO
71
     * @return array
72
     */
73
    protected function getErrorArray($message, $code, ResourceDOInterface $resourceDO = null)
74
    {
75
        $error = [
76
            'error' => [
77
                'title' => $message,
78
                'code' => $code,
79
            ],
80
        ];
81
        if ($resourceDO) {
82
            $error['error']['detail']['resource'] = $resourceDO->toArray();
83
        }
84
85
        return $error;
86
    }
87
88
    /**
89
     * @param $error
90
     * @param $className
91
     * @return string
92
     */
93
    protected function getErrorCode($error, $className)
94
    {
95
        return $error->getCode() . '.' . ExceptionCodes::code($className) . '.' . $error->getLine();
96
    }
97
}