0

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

4

1 回答 1

0

如果它只是关于 OCP,你可以使用责任链设计模式,你可以创建一个类(它是 open-for-extension close-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(你会以同样的方式实现它),所以添加任何其他异常将是当您创建链时(例如,在您的应用程序中提供依赖注入的 Provider 中),只需创建另一个扩展类NodeInErrorHandlerChain,并将其设置为链的上一个最后一个元素。$next

    $this->app->singleton(NodeInErrorHandlerChain::class, function ($app) {
        return new ModelNotFoundNode(ValidationExceptionNode(null));
    });
于 2020-02-10T13:52:20.840 回答