文章目录
- 在 Hyperf 里,业务代码都运行在 Worker 进程 上,也就意味着一旦任意一个请求的业务存在没有捕获处理的异常的话,都会导致对应的 Worker 进程 被中断退出,这对服务而言也是不能接受的,捕获异常并输出合理的报错内容给客户端也是更加友好的。 我们可以通过对各个 server 定义不同的 异常处理器(ExceptionHandler),一旦业务流程存在没有捕获的异常,都会被传递到已注册的 异常处理器(ExceptionHandler) 去处理。
- touch app/Exception/Handler/ResourceExceptionHandler.php<?php namespace AppExceptionHandler;use HyperfContractStdoutLoggerInterface; use HyperfDiAnnotationInject; use HyperfExceptionHandlerExceptionHandler; use HyperfHttpMessageStreamSwooleStream; use PsrHttpMessageResponseInterface; use Throwable;class ResourceExceptionHandler extends ExceptionHandler { /** * @var StdoutLoggerInterface */ protected logger;/** * @Inject() * @var HyperfHttpServerContractResponseInterface */ protectedresponse;public function __construct(StdoutLoggerInterface logger) {this->logger = logger; }public function handle(Throwablethrowable, ResponseInterface response) { // 不再往下传递异常错误this->stopPropagation(); // 将错误的信息返回出去 return this->response->json([ 'error' => 500, 'data' => [] ]); }/** * 确定当前的异常处理程序是否应该处理异常。 */ public function isValid(Throwablethrowable): bool { return $throwable instanceof AppExceptionResourceException; } }
- touch app/Exception/ResourceException.php<?php namespace AppException;class ResourceException extends RuntimeException {}
- <?phpreturn [ 'handler' => [ 'http' => [ HyperfHttpServerExceptionHandlerHttpExceptionHandler::class, AppExceptionHandlerAppExceptionHandler::class, // 注册之前定义好的错误处理类 AppExceptionHandlerResourceExceptionHandler::class ], ], ];
- <?php namespace AppController;use AppExceptionResourceException; use HyperfHttpServerAnnotationAutoController; use HyperfHttpServerAnnotationMiddleware; use HyperfHttpServerAnnotationMiddlewares;/** * @AutoController() */ class IndexController extends AbstractController { public function index() { throw new ResourceException(); } }
在 Hyperf 里,业务代码都运行在 Worker 进程 上,也就意味着一旦任意一个请求的业务存在没有捕获处理的异常的话,都会导致对应的 Worker 进程 被中断退出,这对服务而言也是不能接受的,捕获异常并输出合理的报错内容给客户端也是更加友好的。 我们可以通过对各个 server 定义不同的 异常处理器(ExceptionHandler),一旦业务流程存在没有捕获的异常,都会被传递到已注册的 异常处理器(ExceptionHandler) 去处理。
touch app/Exception/Handler/ResourceExceptionHandler.php
<?php
namespace AppExceptionHandler;
use HyperfContractStdoutLoggerInterface;
use HyperfDiAnnotationInject;
use HyperfExceptionHandlerExceptionHandler;
use HyperfHttpMessageStreamSwooleStream;
use PsrHttpMessageResponseInterface;
use Throwable;
class ResourceExceptionHandler extends ExceptionHandler
{
/**
* @var StdoutLoggerInterface
*/
protected logger;
/**
* @Inject()
* @var HyperfHttpServerContractResponseInterface
*/
protectedresponse;
public function __construct(StdoutLoggerInterface logger)
{this->logger = logger;
}
public function handle(Throwablethrowable, ResponseInterface response)
{
// 不再往下传递异常错误this->stopPropagation();
// 将错误的信息返回出去
return this->response->json([
'error' => 500,
'data' => []
]);
}
/**
* 确定当前的异常处理程序是否应该处理异常。
*/
public function isValid(Throwablethrowable): bool
{
return $throwable instanceof AppExceptionResourceException;
}
}
touch app/Exception/Handler/ResourceExceptionHandler.php
<?php
namespace AppExceptionHandler;
use HyperfContractStdoutLoggerInterface;
use HyperfDiAnnotationInject;
use HyperfExceptionHandlerExceptionHandler;
use HyperfHttpMessageStreamSwooleStream;
use PsrHttpMessageResponseInterface;
use Throwable;
class ResourceExceptionHandler extends ExceptionHandler
{
/**
* @var StdoutLoggerInterface
*/
protected logger;
/**
* @Inject()
* @var HyperfHttpServerContractResponseInterface
*/
protectedresponse;
public function __construct(StdoutLoggerInterface logger)
{this->logger = logger;
}
public function handle(Throwablethrowable, ResponseInterface response)
{
// 不再往下传递异常错误this->stopPropagation();
// 将错误的信息返回出去
return this->response->json([
'error' => 500,
'data' => []
]);
}
/**
* 确定当前的异常处理程序是否应该处理异常。
*/
public function isValid(Throwablethrowable): bool
{
return $throwable instanceof AppExceptionResourceException;
}
}
touch app/Exception/ResourceException.php
<?php
namespace AppException;
class ResourceException extends RuntimeException
{
}
touch app/Exception/ResourceException.php
<?php
namespace AppException;
class ResourceException extends RuntimeException
{
}
<?php
return [
'handler' => [
'http' => [
HyperfHttpServerExceptionHandlerHttpExceptionHandler::class,
AppExceptionHandlerAppExceptionHandler::class,
// 注册之前定义好的错误处理类
AppExceptionHandlerResourceExceptionHandler::class
],
],
];
<?php
return [
'handler' => [
'http' => [
HyperfHttpServerExceptionHandlerHttpExceptionHandler::class,
AppExceptionHandlerAppExceptionHandler::class,
// 注册之前定义好的错误处理类
AppExceptionHandlerResourceExceptionHandler::class
],
],
];
<?php
namespace AppController;
use AppExceptionResourceException;
use HyperfHttpServerAnnotationAutoController;
use HyperfHttpServerAnnotationMiddleware;
use HyperfHttpServerAnnotationMiddlewares;
/**
* @AutoController()
*/
class IndexController extends AbstractController
{
public function index()
{
throw new ResourceException();
}
}
<?php
namespace AppController;
use AppExceptionResourceException;
use HyperfHttpServerAnnotationAutoController;
use HyperfHttpServerAnnotationMiddleware;
use HyperfHttpServerAnnotationMiddlewares;
/**
* @AutoController()
*/
class IndexController extends AbstractController
{
public function index()
{
throw new ResourceException();
}
}


