如何拦截 ZendFramework 3 中的异常
How can I intercept exceptions in ZendFramework 3
我在我的 REST API 项目中使用 ZendFramework 3。所以有几个模块和一个检查授权状态的插件。如果授权失败,它会抛出异常。
无法在每个控制器中使用 try .. catch 分别处理它。如何拦截和处理异常并生成这样的 JSON 输出?
{
message: "Access denied",
reason: "Your token is incorrect"
}
我是 ZendFramework 的新手,所以我不知道该怎么做。官方文档对此只字未提。
有 default framework Events 被触发,包括事件 MvcEvent::EVENT_DISPATCH_ERROR。因此,您应该做的就是在该错误事件上附加侦听器和 return JSON 响应。
首先,您需要在 module.config.php
中注册您的监听器
// In my case module name is Api
'listeners' => [
Api\Listener\ApiListener::class // Register the class listener
],
'service_manager' => [
'invokables' => [
// Register the class (of course you can use Factory)
Api\Listener\ApiListener::class => Api\Listener\ApiListener::class
],
],
其次,创建文件class Api/Listener/ApiListener.php
<?php
namespace Api\Listener;
use Zend\EventManager\AbstractListenerAggregate;
use Zend\EventManager\EventManagerInterface;
use Zend\Mvc\MvcEvent;
use Zend\Console\Request as ConsoleRequest;
use Zend\View\Model\JsonModel;
class ApiListener extends AbstractListenerAggregate
{
public function attach(EventManagerInterface $events, $priority = 1)
{
// Registr the method which will be triggered on error
$this->listeners[] = $events->attach(MvcEvent::EVENT_DISPATCH_ERROR,
[$this, 'handleError'], 0);
}
/**
* Return JSON error on API URI(s)
*/
public function handleError(MvcEvent $e)
{
$request = $e->getParam('application')->getRequest();
if($request instanceof ConsoleRequest){
return;
}
//If you want to convert Response only on some URIs
//$uri = $request->getUri()->getPath();
//if(0 !== strpos($uri, '/api')){
// return;
//}
$response = $e->getResponse();
$exception = $e->getResult()->exception;
$errorType = $e->getError();
$errorCode = $exception && $exception->getCode() ? $exception->getCode() : 500;
$errorMsg = $exception ? $exception->getMessage() : $errorType;
$json = new JsonModel(['message' => $errorMsg]);
$json->setTerminal(true);
$response->setStatusCode($errorCode);
$e->setResult($json);
$e->setViewModel($json);
}
}
就是这样。现在,对于每个错误,您的自定义逻辑都将被执行。
我在我的 REST API 项目中使用 ZendFramework 3。所以有几个模块和一个检查授权状态的插件。如果授权失败,它会抛出异常。
无法在每个控制器中使用 try .. catch 分别处理它。如何拦截和处理异常并生成这样的 JSON 输出?
{
message: "Access denied",
reason: "Your token is incorrect"
}
我是 ZendFramework 的新手,所以我不知道该怎么做。官方文档对此只字未提。
有 default framework Events 被触发,包括事件 MvcEvent::EVENT_DISPATCH_ERROR。因此,您应该做的就是在该错误事件上附加侦听器和 return JSON 响应。
首先,您需要在 module.config.php
中注册您的监听器// In my case module name is Api
'listeners' => [
Api\Listener\ApiListener::class // Register the class listener
],
'service_manager' => [
'invokables' => [
// Register the class (of course you can use Factory)
Api\Listener\ApiListener::class => Api\Listener\ApiListener::class
],
],
其次,创建文件class Api/Listener/ApiListener.php
<?php
namespace Api\Listener;
use Zend\EventManager\AbstractListenerAggregate;
use Zend\EventManager\EventManagerInterface;
use Zend\Mvc\MvcEvent;
use Zend\Console\Request as ConsoleRequest;
use Zend\View\Model\JsonModel;
class ApiListener extends AbstractListenerAggregate
{
public function attach(EventManagerInterface $events, $priority = 1)
{
// Registr the method which will be triggered on error
$this->listeners[] = $events->attach(MvcEvent::EVENT_DISPATCH_ERROR,
[$this, 'handleError'], 0);
}
/**
* Return JSON error on API URI(s)
*/
public function handleError(MvcEvent $e)
{
$request = $e->getParam('application')->getRequest();
if($request instanceof ConsoleRequest){
return;
}
//If you want to convert Response only on some URIs
//$uri = $request->getUri()->getPath();
//if(0 !== strpos($uri, '/api')){
// return;
//}
$response = $e->getResponse();
$exception = $e->getResult()->exception;
$errorType = $e->getError();
$errorCode = $exception && $exception->getCode() ? $exception->getCode() : 500;
$errorMsg = $exception ? $exception->getMessage() : $errorType;
$json = new JsonModel(['message' => $errorMsg]);
$json->setTerminal(true);
$response->setStatusCode($errorCode);
$e->setResult($json);
$e->setViewModel($json);
}
}
就是这样。现在,对于每个错误,您的自定义逻辑都将被执行。