Laravel5实现用户友好的错误页面非常简单,例如想要返回status 404,只需要在
view/errors
中添加一个404.blade.php
文件即可。Lumen中没有默认实现这种便利,于是自己添加一个。
Lumen如何实现类Laravel5用户友好的错误页面
原理
抛出错误的函数是abort()
, 进入该函数一看究竟,会发现只是抛出一个HttpException
. 在Application中,处理http request的时候,有一个try catch的过程,Exception就是在这里被捕获的。
try {
return $this->sendThroughPipeline($this->middleware, function () use ($method, $pathInfo) {
if (isset($this->routes[$method.$pathInfo])) {
return $this->handleFoundRoute([true, $this->routes[$method.$pathInfo]['action'], []]);
}
return $this->handleDispatcherResponse(
$this->createDispatcher()->dispatch($method, $pathInfo)
);
});
} catch (Exception $e) {
return $this->sendExceptionToHandler($e);
}
接着可以看出,Exception是交给了sendExceptionToHandler
去处理了。这里的handler具体是哪个类呢?是实现了Illuminate\Contracts\Debug\ExceptionHandler
的一个单例。为啥说他是单例?因为在bootstrap的时候,已经初始化为单例了,请看。
$app->singleton(
Illuminate\Contracts\Debug\ExceptionHandler::class,
App\Exceptions\Handler::class
);
进入该类看一下,他有一个render
方法,好吧,找到问题所在了,修改一下这个方法即可。
public function render($request, Exception $e)
{
return parent::render($request, $e);
}
动手修改
由于Laravel已经有实现了,所以最简便的方法就是复制黏贴。在render
中先判断下是否为HttpException
, 如果是,就去errors
目录下找对应status code的view,如果找到,就渲染它输出。就这么简单。修改Handler
如下:
/**
* Render an exception into an HTTP response.
*
* @param \Illuminate\Http\Request $request
* @param \Exception $e
* @return \Illuminate\Http\Response
*/
public function render($request, Exception $e)
{
if( !env('APP_DEBUG') and $this->isHttpException($e)) {
return $this->renderHttpException($e);
}
return parent::render($request, $e);
}
/**
* Render the given HttpException.
*
* @param \Symfony\Component\HttpKernel\Exception\HttpException $e
* @return \Symfony\Component\HttpFoundation\Response
*/
protected function renderHttpException(HttpException $e)
{
$status = $e->getStatusCode();
if (view()->exists("errors.{$status}"))
{
return response(view("errors.{$status}", []), $status);
}
else
{
return (new SymfonyExceptionHandler(env('APP_DEBUG', false)))->createResponse($e);
}
}
/**
* Determine if the given exception is an HTTP exception.
*
* @param \Exception $e
* @return bool
*/
protected function isHttpException(Exception $e)
{
return $e instanceof HttpException;
}
好了,在errors
目录下新建一个404.blade.php
文件,在controller中尝试 abort(404)
看一下吧。