【问题标题】:Custom error page not showing on Laravel 5Laravel 5 上未显示自定义错误页面
【发布时间】:2015-06-02 20:00:45
【问题描述】:

我正在尝试显示自定义错误页面而不是默认的 Laravel 5 消息:

“哎呀……好像出了点问题”

在发布之前我进行了很多搜索,我尝试了这个解决方案,它应该可以在 Laravel 5 上运行,但没有运气:https://laracasts.com/discuss/channels/laravel/change-whoops-looks-like-something-went-wrong-page

这是我在app/Exceptions/Handler.php 文件中的确切代码:

<?php namespace App\Exceptions;

use Exception;
use View;
use Bugsnag\BugsnagLaravel\BugsnagExceptionHandler as ExceptionHandler;

class Handler extends ExceptionHandler {

    protected $dontReport = [
        'Symfony\Component\HttpKernel\Exception\HttpException'
    ];

    public function report(Exception $e)
    {
        return parent::report($e);
    }

    public function render($request, Exception $e)
    {
        return response()->view('errors.defaultError');
    }

}

但是,不是显示我的自定义视图,而是显示一个空白页面。我还尝试在render() 函数中使用此代码

return "Hello, I am an error message";

但我得到相同的结果:空白页

【问题讨论】:

    标签: php laravel error-handling


    【解决方案1】:

    在您的 Routes.php 中为您的错误页面创建一个名为“errors.defaultError”的路由,而不是响应。例如

    route::get('error', [
        'as' => 'errors.defaultError',
        'uses' => 'ErrorController@defaultError' ]);
    

    要么制作一个控制器,要么在路由中包含该函数

    return view('errors.defaultError');
    

    并改用重定向。例如

    public function render($request, Exception $e)
    {
        return redirect()->route('errors.defaultError');
    }
    

    【讨论】:

    • 成功了。您刚刚忘记了 'uses' =&gt; 'ErrorController@defaultError ]); 代码中的引用,但非常感谢您
    • 你知道为什么不能简单地在Handler.php render()函数中返回errors.defaultError页面吗?
    • @Justin 我也有同样的问题……你发现原因了吗?当我使用routeredirects 时效果很好,但是当我直接返回view 时不起作用。 (带有刀片模板的视图
    • 这会隐藏正常的 HTTP 响应并将浏览器重定向到不同的资源。
    • @tomloprod 返回response()-&gt;view 也可以,但是如果您尝试使用extends('errors::layout...') 附带的默认刀片错误页面,您可能会遇到空白页面或错误页面,具体取决于您的网络服务器配置。问题是默认的 laravel 错误模板使用自定义提示路径。
    【解决方案2】:

    我非常同意每个想要在 Laravel 中自定义错误体验的人,这样他们的用户就不会看到诸如“哎呀,好像出了点问题”之类的尴尬消息。

    我花了 永远 才弄明白。

    如何在 Laravel 5.3 中自定义“哎呀”消息

    app/Exceptions/Handler.php中,用这个替换整个prepareResponse函数:

    protected function prepareResponse($request, Exception $e)
    {        
        if ($this->isHttpException($e)) {            
            return $this->toIlluminateResponse($this->renderHttpException($e), $e);
        } else {
            return response()->view("errors.500", ['exception' => $e]); //By overriding this function, I make Laravel display my custom 500 error page instead of the 'Whoops, looks like something went wrong.' message in Symfony\Component\Debug\ExceptionHandler
        }
    }
    

    基本上,它与原始功能几乎相同,但您只是更改 else 块以呈现视图。

    /resources/views/errors 中,创建500.blade.php

    你可以在那里写任何你想要的文本,但我总是建议保持错误页面非常基本(纯 HTML 和 CSS,没有什么花哨的),这样它们本身导致进一步错误的可能性几乎为零。

    测试它是否有效

    routes/web.php,您可以添加:

    Route::get('error500', function () {
        throw new \Exception('TEST PAGE. This simulated error exception allows testing of the 500 error page.');
    });
    

    然后我会浏览到mysite.com/error500 并查看您是否看到您自定义的错误页面。

    然后也浏览到mysite.com/some-nonexistent-route,看看你是否仍然得到你设置的404页面,假设你有一个。

    【讨论】:

    • app/Exceptions/Handler.php文件中没有prepareResponse这样的函数。是的,我使用的是 5.3。我有以下功能reportrenderunauthenticated。你自己加的吗?顺便说一句,您能否发布您的整个Hadler.php file? 以确保我们拥有相同的东西?谢谢!
    • @Eitan 我可能的意思是您将覆盖该文件扩展的类的功能。因此,只需尝试将其添加到 app/Exceptions/Handler.php 中,看看它是否有效。看看你的文件怎么说class Handler extends ExceptionHandler?您可以浏览到 vendor/laravel/framework/src/Illuminate/Foundation/Exceptions/Handler.php 并在那里查看原始的 prepareResponse 函数。通过在app/Exceptions/Handler.php 中创建您的自己的 prepareResponse,您将覆盖原来的。
    • 我将代码放在render函数中,效果很好。
    【解决方案3】:

    我有两个错误页面 - 404.blade.php & generic.blade.php

    我想要:

    • 404 页显示所有缺失的页面
    • 开发中异常的异常页面
    • 生产中异常的通用错误页面

    我正在使用 .env - APP_DEBUG 来决定这一点。

    我更新了异常处理程序中的渲染方法:

    app/Exceptions/Handler.php

    public function render($request, Exception $e)
    {
        if ($e instanceof ModelNotFoundException) {
            $e = new NotFoundHttpException($e->getMessage(), $e);
        }
    
        if ($this->isUnauthorizedException($e)) {
            $e = new HttpException(403, $e->getMessage());
        }
    
        if ($this->isHttpException($e)) {
            // Show error for status code, if it exists
            $status = $e->getStatusCode();
            if (view()->exists("errors.{$status}")) {
                return response()->view("errors.{$status}", ['exception' => $e], $status);
            }
        }
    
        if (env('APP_DEBUG')) {
            // In development show exception
            return $this->toIlluminateResponse($this->convertExceptionToResponse($e), $e);
        }
        // Otherwise show generic error page
        return $this->toIlluminateResponse(response()->view("errors.generic"), $e);
    
    }
    

    【讨论】:

      【解决方案4】:

      在您的 app/exceptions/handler.php 上的 Larvel 5.2 上,只需扩展此方法 renderHttpException 即将此方法添加到 handler.php 自定义您想要的

      /**
       * Render the given HttpException.
       *
       * @param  \Symfony\Component\HttpKernel\Exception\HttpException  $e
       * @return \Symfony\Component\HttpFoundation\Response
       */
      protected function renderHttpException(HttpException $e)
      {
      
         // to get status code ie 404,503
          $status = $e->getStatusCode();
      
          if (view()->exists("errors.{$status}")) {
              return response()->view("errors.{$status}", ['exception' => $e], $status, $e->getHeaders());
          } else {
              return $this->convertExceptionToResponse($e);
          }
      }
      

      【讨论】:

      • 这不会处理 500 错误,这是这个问题所问的。相反,您需要使用:protected function convertExceptionToResponse(Exception $e) { $status = $e-&gt;getCode(); if ($status == 500) { $view500 = config('app.debug') ? "errors.500_dev" : "errors.500"; return response()-&gt;view($view500, ['exception' =&gt; $e], 500); } else { return parent::convertExceptionToResponse($e); } }
      【解决方案5】:

      在 laravel 5.4 中,您可以将此代码块放在 Handler.php 中的 render 函数中 - 在 app/exceptions/Handler.php 中找到

        //Handle TokenMismatch Error/session('csrf_error')
          if ($exception instanceof TokenMismatchException) {
              return response()->view('auth.login', ['message' => 'any custom message'] );
          }
      
          if ($this->isHttpException($exception)){       
              if($exception instanceof NotFoundHttpException){
                  return response()->view("errors.404");
              }
              return $this->renderHttpException($exception);
          }
      
          return response()->view("errors.500");
          //return parent::render($request, $exception);
      

      【讨论】:

      • 您的答案被标记为低质量,因为它是纯代码的。请解释一下。
      【解决方案6】:

      执行此操作的典型方法是 create individual views for each error type

      我想要一个动态的自定义错误页面(所以所有错误都出现在同一个刀片模板中)。

      在 Handler.php 中我使用了:

      public function render($request, Exception $e)
      {
          // Get error status code.
          $statusCode = method_exists($e, 'getStatusCode') ? $e->getStatusCode() : 400;
          $data = ['customvar'=>'myval'];
          return response()->view('errors.index', $data, $statusCode);
      }
      

      那么我不必为每个可能的 http 错误状态代码创建 20 个错误页面。

      【讨论】:

      • 您的索引视图是从刀片模板扩展而来的?据我所知(我不知道为什么)在ExcepcionHandlerrender 方法内直接返回视图(没有路由)不起作用与刀片模板很好。
      猜你喜欢
      • 2017-08-10
      • 1970-01-01
      • 1970-01-01
      • 2016-08-18
      • 1970-01-01
      • 1970-01-01
      • 2012-12-25
      • 2013-08-04
      • 1970-01-01
      相关资源
      最近更新 更多