Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 61 |
|
0.00% |
0 / 2 |
CRAP | |
0.00% |
0 / 1 |
AppErrorHandler | |
0.00% |
0 / 61 |
|
0.00% |
0 / 2 |
132 | |
0.00% |
0 / 1 |
__construct | |
0.00% |
0 / 4 |
|
0.00% |
0 / 1 |
2 | |||
catchError | |
0.00% |
0 / 57 |
|
0.00% |
0 / 1 |
110 |
1 | <?php |
2 | |
3 | declare(strict_types=1); |
4 | |
5 | namespace PeServer\App\Models; |
6 | |
7 | use PeServer\Core\DI\Inject; |
8 | use PeServer\Core\Environment; |
9 | use PeServer\Core\Errors\ErrorHandler; |
10 | use PeServer\Core\Errors\HttpErrorHandler; |
11 | use PeServer\Core\Http\ContentType; |
12 | use PeServer\Core\Http\HttpRequest; |
13 | use PeServer\Core\Http\HttpResponse; |
14 | use PeServer\Core\Http\IResponsePrinterFactory; |
15 | use PeServer\Core\Http\RequestPath; |
16 | use PeServer\Core\IO\Directory; |
17 | use PeServer\Core\IO\Path; |
18 | use PeServer\Core\Log\ILogger; |
19 | use PeServer\Core\Log\Logging; |
20 | use PeServer\Core\Log\NullLogger; |
21 | use PeServer\Core\Mime; |
22 | use PeServer\Core\Mvc\Template\ITemplateFactory; |
23 | use PeServer\Core\Mvc\Template\TemplateFactory; |
24 | use PeServer\Core\Mvc\Template\TemplateOptions; |
25 | use PeServer\Core\Mvc\Template\TemplateParameter; |
26 | use PeServer\Core\ProgramContext; |
27 | use PeServer\Core\Serialization\JsonSerializer; |
28 | use PeServer\Core\Text; |
29 | use PeServer\Core\Web\IUrlHelper; |
30 | use PeServer\Core\Web\WebSecurity; |
31 | use Throwable; |
32 | |
33 | final class AppErrorHandler extends HttpErrorHandler |
34 | { |
35 | #region variable |
36 | |
37 | private RequestPath $requestPath; |
38 | private JsonSerializer $jsonSerializer; |
39 | private ITemplateFactory $templateFactory; |
40 | |
41 | #endregion |
42 | |
43 | public function __construct( |
44 | RequestPath $requestPath, |
45 | TemplateFactory $templateFactory, |
46 | private IResponsePrinterFactory $responsePrinterFactory, |
47 | private ProgramContext $programContext, |
48 | private IUrlHelper $urlHelper, |
49 | private WebSecurity $webSecurity, |
50 | ?JsonSerializer $jsonSerializer, |
51 | private Environment $environment, |
52 | ILogger $logger |
53 | ) { |
54 | parent::__construct($logger); |
55 | |
56 | $this->requestPath = $requestPath; |
57 | $this->templateFactory = $templateFactory; |
58 | $this->jsonSerializer = $jsonSerializer ?? new JsonSerializer(); |
59 | } |
60 | |
61 | #region ErrorHandler |
62 | |
63 | protected function catchError(int $errorNumber, string $message, string $file, int $lineNumber, ?Throwable $throwable): void |
64 | { |
65 | $next = true; |
66 | |
67 | $isProduction = $this->environment->isProduction(); |
68 | |
69 | if ($isProduction) { |
70 | $next = false; |
71 | } |
72 | |
73 | $isJson = Text::startsWith($this->requestPath->full, 'api/', true) || Text::startsWith($this->requestPath->full, 'ajax/', true); |
74 | if ($isJson) { |
75 | $next = false; |
76 | } |
77 | |
78 | // デバッグ環境で本番用エラー検証用 |
79 | //$next = false; |
80 | |
81 | if (!$next) { |
82 | $response = new HttpResponse(); |
83 | $response->status = $this->getHttpStatus($throwable); |
84 | |
85 | $values = [ |
86 | 'error_number' => $errorNumber, |
87 | 'message' => $message, |
88 | 'file' => $file, |
89 | 'line_number' => $lineNumber, |
90 | 'throwable' => $throwable, |
91 | ]; |
92 | |
93 | $isSuppressionStatus = false; |
94 | foreach ($this->getSuppressionStatusList() as $suppressionStatus) { |
95 | if ($response->status === $suppressionStatus) { |
96 | $isSuppressionStatus = true; |
97 | $this->logger->info('HTTP {0}: {1}', $suppressionStatus->value, $suppressionStatus->name); |
98 | break; |
99 | } |
100 | } |
101 | if (!$isSuppressionStatus) { |
102 | $this->logger->error($values); |
103 | } |
104 | |
105 | if ($isJson) { |
106 | unset($values['error_number']); |
107 | unset($values['message']); |
108 | if ($isProduction) { |
109 | unset($values['throwable']); |
110 | } |
111 | |
112 | $responseJson = ResponseJson::error( |
113 | $message, |
114 | strval($errorNumber), |
115 | $values |
116 | ); |
117 | |
118 | $json = [ |
119 | 'data' => $responseJson->data, |
120 | 'error' => $responseJson->error, |
121 | ]; |
122 | |
123 | $response->header->addValue(ContentType::NAME, Mime::JSON); |
124 | $response->content = $this->jsonSerializer->save($json); |
125 | } else { |
126 | $rootDir = Path::combine($this->programContext->applicationDirectory, 'App', 'Views'); |
127 | $baseDir = Path::combine('template', 'page'); |
128 | |
129 | $options = new TemplateOptions( |
130 | $rootDir, |
131 | $baseDir, |
132 | $this->programContext, |
133 | $this->urlHelper, |
134 | $this->webSecurity, |
135 | Path::combine(Directory::getTemporaryDirectory(), 'PeServer-App') |
136 | ); |
137 | $template = $this->templateFactory->createTemplate($options); |
138 | $response->content = $template->build('error.tpl', new TemplateParameter($response->status, $values, [])); |
139 | } |
140 | |
141 | $printer = $this->responsePrinterFactory->createResponsePrinter(HttpRequest::none(), $response); |
142 | $printer->execute(); |
143 | return; |
144 | } |
145 | |
146 | parent::catchError($errorNumber, $message, $file, $lineNumber, $throwable); |
147 | } |
148 | |
149 | #endregion |
150 | } |