Laravel 异常处理程序
Laravel exceptions handler
我正在使用 Laravel 开发一个项目,在渲染函数中的 Exceptions\Handler.php
中捕获异常,如下所示:
public function render($request, Exception $e){
switch(get_class($e)){
case SOME_EXCEPTION::class:
do something..
...
...
default:
do something..
}
如您所见,问题是在很多情况下代码变得丑陋和混乱
如何解决这个问题?
如果您的自定义异常扩展了一个公共接口,您可以只检查该接口,然后调用契约方法。
if ($e instanceof CustomExceptionInterface) {
return $e->contractMethod();
}
好的,找到了让它看起来更好的方法。
如果有人想在 laravel 中改进他的异常处理程序,请按照以下步骤操作:
在 app/providers 下创建您的新服务提供商,我们将其命名为 ExceptionServiceProvider.php
class ExceptionServiceProvider extends ServiceProvider {
/**
* Register the service provider.
*
* @return void
*/
public function register()
{
$this->app->singleton(ExceptionFactory::class);
}
public function boot(ExceptionFactory $factory){
$factory->addException(UnauthorizedException::class, JsonResponse::HTTP_NOT_ACCEPTABLE);
$factory->addException(ConditionException::class, JsonResponse::HTTP_NOT_ACCEPTABLE, "Some Fixed Error Message");
}
}
在项目的某处创建 ExceptionFactory
class,其中包含 addException()
方法和代码和消息的获取器
class ExceptionFactory{
private $exceptionsMap = [];
private $selectedException;
public function addException($exception, $code, $customMessage = null) {
$this->exceptionsMap[$exception] = [$code, $customMessage];
}
public function getException($exception){
if(isset($this->exceptionsMap[$exception])){
return $this->exceptionsMap[$exception];
}
return null;
}
public function setException($exception){
$this->selectedException = $exception;
}
public function getCode(){
return $this->selectedException[0];
}
public function getCustomMessage(){
return $this->selectedException[1];
}
}
然后剩下要做的就是 Exceptions/handler.php
在渲染函数中:
private $exceptionFactory;
public function __construct(LoggerInterface $log, ExceptionFactory $exceptionFactory){
parent::__construct($log);
$this->exceptionFactory = $exceptionFactory;
}
public function render($request, Exception $e){
$error = new \stdClass();
$customException = $this->exceptionFactory->getException(get_class($e));
if(isset($customException)){
$this->exceptionFactory->setException($customException);
$error->code = $this->exceptionFactory->getCode();
$error->message = $e->getMessage();
$customMessage = $this->exceptionFactory->getCustomMessage();
if(isset($customMessage)){
$error->message = $customMessage;
}
}
return new JsonResponse($error, $error->code);
}
}
最后要记住的是将 ServiceProvider
放在 config/app.php
下的应用程序设置中,只需添加:
\App\Providers\ExceptionServiceProvider::class
我希望你会像我一样觉得这很有用。
我正在使用 Laravel 开发一个项目,在渲染函数中的 Exceptions\Handler.php
中捕获异常,如下所示:
public function render($request, Exception $e){
switch(get_class($e)){
case SOME_EXCEPTION::class:
do something..
...
...
default:
do something..
}
如您所见,问题是在很多情况下代码变得丑陋和混乱
如何解决这个问题?
如果您的自定义异常扩展了一个公共接口,您可以只检查该接口,然后调用契约方法。
if ($e instanceof CustomExceptionInterface) {
return $e->contractMethod();
}
好的,找到了让它看起来更好的方法。 如果有人想在 laravel 中改进他的异常处理程序,请按照以下步骤操作:
在 app/providers 下创建您的新服务提供商,我们将其命名为 ExceptionServiceProvider.php
class ExceptionServiceProvider extends ServiceProvider {
/**
* Register the service provider.
*
* @return void
*/
public function register()
{
$this->app->singleton(ExceptionFactory::class);
}
public function boot(ExceptionFactory $factory){
$factory->addException(UnauthorizedException::class, JsonResponse::HTTP_NOT_ACCEPTABLE);
$factory->addException(ConditionException::class, JsonResponse::HTTP_NOT_ACCEPTABLE, "Some Fixed Error Message");
}
}
在项目的某处创建 ExceptionFactory
class,其中包含 addException()
方法和代码和消息的获取器
class ExceptionFactory{
private $exceptionsMap = [];
private $selectedException;
public function addException($exception, $code, $customMessage = null) {
$this->exceptionsMap[$exception] = [$code, $customMessage];
}
public function getException($exception){
if(isset($this->exceptionsMap[$exception])){
return $this->exceptionsMap[$exception];
}
return null;
}
public function setException($exception){
$this->selectedException = $exception;
}
public function getCode(){
return $this->selectedException[0];
}
public function getCustomMessage(){
return $this->selectedException[1];
}
}
然后剩下要做的就是 Exceptions/handler.php
在渲染函数中:
private $exceptionFactory;
public function __construct(LoggerInterface $log, ExceptionFactory $exceptionFactory){
parent::__construct($log);
$this->exceptionFactory = $exceptionFactory;
}
public function render($request, Exception $e){
$error = new \stdClass();
$customException = $this->exceptionFactory->getException(get_class($e));
if(isset($customException)){
$this->exceptionFactory->setException($customException);
$error->code = $this->exceptionFactory->getCode();
$error->message = $e->getMessage();
$customMessage = $this->exceptionFactory->getCustomMessage();
if(isset($customMessage)){
$error->message = $customMessage;
}
}
return new JsonResponse($error, $error->code);
}
}
最后要记住的是将 ServiceProvider
放在 config/app.php
下的应用程序设置中,只需添加:
\App\Providers\ExceptionServiceProvider::class
我希望你会像我一样觉得这很有用。