转载

Lumen如何实现类Laravel5用户友好的错误页面

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) 看一下吧。

正文到此结束
Loading...