异常的序列化视图变量是硬编码在异常渲染器中的,您必须创建一个自定义/扩展变量来处理自定义异常,以便它可以获取它提供的附加数据。
这是一个快速而肮脏的示例,使用名为的自定义异常ValidationErrorException
(InternalErrorException
已被 CakePHP 核心使用),它扩展了\Cake\Http\Exception\HttpException
,并实现了getValidationErrors()
返回验证错误的方法:
// in src/Error/Exception/ValidationErrorException.php
namespace App\Error\Exception;
use Cake\Datasource\EntityInterface;
use Cake\Http\Exception\HttpException;
class ValidationErrorException extends HttpException
{
protected $_validationErrors;
public function __construct(EntityInterface $entity, $message = null, $code = 422)
{
$this->_validationErrors = $entity->getErrors();
if ($message === null) {
$message = 'A validation error occurred.';
}
parent::__construct($message, $code);
}
public function getValidationErrors()
{
return $this->_validationErrors;
}
}
这样的 HTTP 异常将映射到具有匹配名称的异常呈现器类方法:
// in src/Error/AppExceptionRenderer.php
namespace App\Error;
use App\Error\Exception\ValidationErrorException;
use Cake\Error\ExceptionRenderer;
class AppExceptionRenderer extends ExceptionRenderer
{
// HttpExceptions automatically map to methods matching the inflected variable name
public function validationError(ValidationErrorException $exception)
{
$code = $this->_code($exception);
$method = $this->_method($exception);
$template = $this->_template($exception, $method, $code);
$message = $this->_message($exception, $code);
$url = $this->controller->request->getRequestTarget();
$response = $this->controller->getResponse();
foreach ((array)$exception->responseHeader() as $key => $value) {
$response = $response->withHeader($key, $value);
}
$this->controller->setResponse($response->withStatus($code));
$viewVars = [
'message' => $message,
'url' => h($url),
'error' => $exception,
'code' => $code,
// set the errors as a view variable
'errors' => $exception->getValidationErrors(),
'_serialize' => [
'message',
'url',
'code',
'errors' // mark the variable as to be serialized
]
];
$this->controller->set($viewVars);
return $this->_outputMessage($template);
}
}
在你的控制器中,你可以像这样抛出它,向它提供验证失败的实体:
if (!$this->Categories->save($categoryEntity)) {
throw new \App\Error\Exception\ValidationErrorException($categoryEntity);
}
See also
- Cookbook > 错误和异常处理 > 更改异常渲染器 https://book.cakephp.org/3.0/en/development/errors.html#change-the-exceptionrenderer
- 源 > \Cake\Error\ExceptionRenderer::render() https://github.com/cakephp/cakephp/blob/3.6.2/src/Error/ExceptionRenderer.php#L155