在Laravel 5.3中创建自定义异常类和自定义处理程序类

时间:2016-11-10 09:05:11

标签: exception-handling laravel-5.3 custom-exceptions

在我开始编码之前,让我解释一下我的目标。我的网络应用程序显示待售车辆。我需要一个自定义404页面,如果用户试图访问一个不存在的页面,它将显示添加到数据库中的12个最新车辆。

我有以下......

应用\例外\ CustomException.php

<?php

namespace App\Exceptions;

use Exception;

class CustomException extends Exception
{
    public function __construct()
    {
        parent::__construct();
    }
}

应用\例外\ CustomHandler.php

<?php
namespace App\Exceptions;

use Exception;
use App\Exceptions\Handler as ExceptionHandler;
use Illuminate\Contracts\Container\Container;
use App\Project\Frontend\Repo\Vehicle\EloquentVehicle;
use Illuminate\Foundation\Exceptions\Handler;
use Illuminate\Support\Facades\View;

class CustomHandler extends ExceptionHandler
{
    protected $vehicle;

    public function __construct(Container $container, EloquentVehicle $vehicle)
    {
        parent::__construct($container);

        $this->vehicle = $vehicle;
    }

    /**
     * Report or log an exception.
     *
     * This is a great spot to send exceptions to Sentry, Bugsnag, etc.
     *
     * @param  \Exception  $exception
     * @return void
     */
    public function report(Exception $exception)
    {
        parent::report($exception);
    }

    /**
     * Render an exception into an HTTP response.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Exception  $exception
     * @return \Illuminate\Http\Response
     */
    public function render($request, Exception $exception)
    {
        $exception = Handler::prepareException($exception);

        if($exception instanceof CustomException) {
            return $this->showCustomErrorPage();
        }

        return parent::render($request, $exception);
    }

    public function showCustomErrorPage()
    {
        $recentlyAdded = $this->vehicle->fetchLatestVehicles(0, 12);

        return View::make('errors.404Custom')->with('recentlyAdded', $recentlyAdded);
    }
}

为了测试这个,我添加了

  

抛出新的CustomException();

到我的控制器,但它没有显示404Custom视图。我需要做些什么来实现这个目标?

更新:对于任何将其班级限制在其模型中的人来说,这只是一个注释。如果您尝试使用以下方法访问类中的函数,则会收到BindingResolutionException:

应用(MyClass的::类) - &GT; functionNameGoesHere();

要解决这个问题,只需创建一个变量,就像将类绑定到服务提供者中的Container一样。

我的代码如下所示:

protected function showCustomErrorPage()
{
    $eloquentVehicle = new EloquentVehicle(new Vehicle(), new Dealer());
    $recentlyAdded = $eloquentVehicle->fetchLatestVehicles(0, 12);

    return view()->make('errors.404Custom')->with('recentlyAdded', $recentlyAdded);
}

阿米特的版本

protected function showCustomErrorPage()
{
    $recentlyAdded = app(EloquentVehicle::class)->fetchLatestVehicles(0, 12);

    return view()->make('errors.404Custom')->with('recentlyAdded', $recentlyAdded);
}

2 个答案:

答案 0 :(得分:3)

Laravel调用render类的App\Exceptions\Handler函数。所以压倒它是行不通的。

您必须仅在App\Exceptions\Handler课程中添加。

例如:

<?php

namespace App\Exceptions;

use Exception;
use Illuminate\Auth\AuthenticationException;
use App\Project\Frontend\Repo\Vehicle\EloquentVehicle;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;

class Handler extends ExceptionHandler
{
    /**
     * A list of the exception types that should not be reported.
     *
     * @var array
     */
    protected $dontReport = [
        \Illuminate\Auth\AuthenticationException::class,
        \Illuminate\Auth\Access\AuthorizationException::class,
        \Symfony\Component\HttpKernel\Exception\HttpException::class,
        \Illuminate\Database\Eloquent\ModelNotFoundException::class,
        \Illuminate\Session\TokenMismatchException::class,
        \Illuminate\Validation\ValidationException::class,
    ];

    /**
     * Report or log an exception.
     *
     * This is a great spot to send exceptions to Sentry, Bugsnag, etc.
     *
     * @param  \Exception  $exception
     * @return void
     */
    public function report(Exception $exception)
    {
        parent::report($exception);
    }

    /**
     * Render an exception into an HTTP response.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Exception  $exception
     * @return \Illuminate\Http\Response
     */
    public function render($request, Exception $exception)
    {
        if($exception instanceof CustomException) {
            return $this->showCustomErrorPage();
        }

        return parent::render($request, $exception);
    }

    protected function showCustomErrorPage()
    {
        $recentlyAdded = app(EloquentVehicle::class)->fetchLatestVehicles(0, 12);

        return view()->make('errors.404Custom')->with('recentlyAdded', $recentlyAdded);
    }
}

答案 1 :(得分:1)

在新版本的Laravel中,您可以使用以下命令创建自定义处理程序:

php artisan make:exception CustomException

然后,您应该在自定义处理程序中调用这些方法“ report() render()”,它们将覆盖App\Exceptions\Handler中的现有方法

report()用于记录错误。

render(),如果您想重定向到错误或返回HTTP响应(例如您自己的Blade文件),或者正在构建API,则使用该

有关更多信息,您可以检查Laravel documentation