【问题标题】:Handle exceptions in laravel without type-checking exceptions in the exception handler's render method and without defining custom exception?在 laravel 中处理异常而不在异常处理程序的渲染方法中进行类型检查异常并且不定义自定义异常?
【发布时间】:2020-05-25 19:07:41
【问题描述】:

我正在通过异常处理程序的render方法中的类型检查异常来处理诸如NotFoundHttpExceptionUnauthorizedException之类的laravel异常,赚了很多instanceof 检查在我看来违反了 OCP(对扩展开放,对修改关闭)原则。 该文档通过使用必须从我不想要的控制器(或任何地方)抛出的可渲染异常(https://laravel.com/docs/6.x/errors#renderable-exceptions)解决了这个问题,我想捕获 laravel 异常,例如 ModelNotFoundException处理程序类并以干净的方式返回我的自定义响应,换句话说,我正在寻找一种干净的方式来处理 laravel 异常而不从控制器抛出异常。

【问题讨论】:

  • 该框架为您提供了两种处理异常的方法,您似乎都不满意。为什么需要这种级别的微调控制?如果您只是想在发生给定异常时更改页面上显示的内容,您可以通过创建自己的文件来覆盖刀片文件,例如resources/views/errors/404.blade.php。或者您是否还有其他需要实现的条件逻辑?

标签: laravel exception laravel-exceptions


【解决方案1】:

如果只是关于 OCP,你可以使用责任链设计模式,你可以创建一个类(它是 open-for-extension closed-for-modifications),它有一个“next”字段,它是来自相同的类类型,并进行您想要的转换:

interface ErrorHandler {
    function handleError($request);
}

abstract class NodeInErrorHandlerChain {
    private $next; // It should have the same `NodeInErrorHandlerChain` type

    public NodeInErrorHandlerChain($next) {
        $this->next = $next;
    }

    abstract protected function currentHandler($exception, $request);

    public function handle($exception, $request) {
        $current = currentHandler($exception, $request);
        return $current != null ? $current : 
              ($next == null ? null : $next->handle($exception, $request));
    }
}

然后实现如下:

class ModelNotFoundNode extends NodeInErrorHandlerChain {
    protected function currentHandler($exception, $request) {
        if($exception instanceof ModelNotFoundException) {
            return ModelNotFoundHandler($request); // This should be easy to implement
        }
    }
}

所以,现在你只检查ModelNotFoundException,如果你想检查其他类型,创建ModelNotFoundNode$next不等于null,而是等于例如ValidationException(你可以实现以相同的方式),因此添加任何其他例外只会创建另一个扩展NodeInErrorHandlerChain的类,并在创建链时将$next设置为链的前一个最后一个元素(例如在在您的应用中提供依赖注入的 Provider)。

    $this->app->singleton(NodeInErrorHandlerChain::class, function ($app) {
        return new ModelNotFoundNode(ValidationExceptionNode(null));
    });

【讨论】:

  • 好的,我会试试这个。谢谢
猜你喜欢
  • 1970-01-01
  • 2015-07-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-07
  • 1970-01-01
  • 2019-07-15
  • 1970-01-01
相关资源
最近更新 更多