/
ErrorHandler.php
149 lines (140 loc) · 4.62 KB
/
ErrorHandler.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
<?php
/**
* slince application library
* @author Tao <taosikai@yeah.net>
*/
namespace Slince\Application;
use Slince\Event\SubscriberInterface;
use Slince\Event\Event;
use Slince\Application\Exception\NotFoundException;
use Slince\Routing\Exception\RouteNotFoundException;
use Symfony\Component\HttpFoundation\Response;
class ErrorHandler implements SubscriberInterface
{
function getEvents()
{
return [
EventStore::ERROR_OCCURRED => 'onError',
EventStore::EXCEPTION_OCCURRED => 'onException'
];
}
/**
* 错误发生时的捕获
* @param Event $event
*/
function onError(Event $event)
{
$event->stopPropagation();
$kernel = $event->getSubject();
$application = $kernel->getDispatchedApplication();
$content = $this->getErrorContent($application, [
'path' => $kernel->getParameter('request')->getPathInfo(),
'message' => $event->getArgument(1)
]);
$response = $this->createResponse($content, 500);
$kernel->sendResponse($response);
}
/**
* 异常发生时的默认捕获
* @param Event $event
*/
function onException(Event $event)
{
$event->stopPropagation();
$exception = $event->getArgument('exception');
$kernel = $event->getSubject();
$application = $kernel->getDispatchedApplication();
$parameters = [
'path' => $kernel->getParameter('request')->getPathInfo(),
'message' => $exception->getMessage()
];
//基于NotFoundException抛出的异常会渲染成404错误
if ($exception instanceof NotFoundException || $exception instanceof RouteNotFoundException) {
$status = 404;
$content = $this->getNotFoundContent($kernel, $application, $parameters);
} else {
$status = 500;
$content = $this->getErrorContent($application, $parameters);
}
$response = $this->createResponse($content, $status);
$kernel->sendResponse($response);
}
/**
* 获取404错误对应的错误内容
* @param Kernel $kernel
* @param Application $application
* @param array $parameters
* @return string
*/
protected function getNotFoundContent(Kernel $kernel, Application $application = null, array $parameters = [])
{
if (! is_null($application)) {
$content = $this->renderContentFromView($application, '404', $parameters);
} else {
$content = <<<EOT
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>404 Not Found</title>
</head><body>
<h1>Not Found</h1>
<p>The requested URL {$kernel->getParameter('request')->getPathInfo()} was not found on this server.</p>
</body></html>
EOT;
}
return $content;
}
/**
* 获取500错误内容
* @param Application $application
* @param array $parameters
* @return string
*/
protected function getErrorContent(Application $application = null, array $parameters = [])
{
//如果错误发生在application级别,则渲染application对应的错误模版
//否则使用默认错误
if (! is_null($application)) {
$content = $this->renderContentFromView($application, '500', $parameters);
} else {
$content = <<<EOT
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>500 Internal Server Error</title>
</head><body>
<h1>Internal Server Error</h1>
<p>The server encountered an internal error or
misconfiguration and was unable to complete
your request.</p>
<p>Please contact the server administrator and inform them of the time the error occurred,
and anything you might have done that may have
caused the error.</p>
<p>More information about this error may be available
in the server error log.</p>
</body></html>
EOT;
}
return $content;
}
/**
* 从Application的错误模板渲染内容
* @param Application $application
* @param string $templateName
* @param array $parameters
*/
protected function renderContentFromView(Application $application, $templateName, array $parameters = [])
{
$viewManager = $application->getViewManager();
$viewManager->setViewPath($application->getViewPath() . '/error/');
return $viewManager->load($templateName)->render($parameters);
}
/**
* 生成Response对象
* @param string $content
* @param int $status
* @return Response
*/
protected function createResponse($content, $status)
{
return new Response($content, $status);
}
}