如何在您的扩展程序中抛出异常?
How to throw an exception in your Extension?
在 Extbase 扩展中,可能需要通知用户错误或异常。
在我的例子中,我必须解析来自潜在不良来源的一些数据。因此扩展程序必须验证此数据。而如果数据无效,则需要抛出一个异常,然后由TYPO3处理。
但是,我只能找到有关异常和错误处理程序如何工作的信息,但找不到有关如何从扩展内部正确抛出异常的信息。
那么从 Extbase 扩展内部抛出异常的预期方法是什么?
预期结果
如果我产生语法错误,TYPO3 会显示类似如下的消息:
(摘自 the core API reference。)
这就是我所期望的 正确 抛出错误或异常的样子。
我试过的
编辑:我尝试抛出这样的错误:
throw new \Exception('Invalid data');
但是,所有的前端显示都是
Oops, an error occurred! Code: 20160721101726b5339896
产生错误的另一种可能方式:
$GLOBALS['TSFE']->pageNotFoundAndExit('Invalid data');
但是,这显示页面未找到错误而不是预期的异常。
namespace VendorName\ExtensionName\Controller;
abstract class ActionController extends \TYPO3\CMS\Extbase\Mvc\Controller\ActionController {
/**
* @var string
*/
protected $entityNotFoundMessage = 'The requested entity could not be found.';
/**
* @var string
*/
protected $unknownErrorMessage = 'An unknown error occurred. The wild monkey horde in our basement will try to fix this as soon as possible.';
/**
* @param \TYPO3\CMS\Extbase\Mvc\RequestInterface $request
* @param \TYPO3\CMS\Extbase\Mvc\ResponseInterface $response
* @return void
* @throws \Exception
* @override \TYPO3\CMS\Extbase\Mvc\Controller\ActionController
*/
public function processRequest(\TYPO3\CMS\Extbase\Mvc\RequestInterface $request, \TYPO3\CMS\Extbase\Mvc\ResponseInterface $response) {
try {
parent::processRequest($request, $response);
}
catch(\Exception $exception) {
// If the property mapper did throw a \TYPO3\CMS\Extbase\Property\Exception, because it was unable to find the requested entity, call the page-not-found handler.
$previousException = $exception->getPrevious();
if (($exception instanceof \TYPO3\CMS\Extbase\Property\Exception) && (($previousException instanceof \TYPO3\CMS\Extbase\Property\Exception\TargetNotFoundException) || ($previousException instanceof \TYPO3\CMS\Extbase\Property\Exception\InvalidSourceException))) {
$GLOBALS['TSFE']->pageNotFoundAndExit($this->entityNotFoundMessage);
}
throw $exception;
}
}
/**
* @return void
* @override \TYPO3\CMS\Extbase\Mvc\Controller\ActionController
*/
protected function callActionMethod() {
try {
parent::callActionMethod();
}
catch(\Exception $exception) {
// This enables you to trigger the call of TYPO3s page-not-found handler by throwing \TYPO3\CMS\Core\Error\Http\PageNotFoundException
if ($exception instanceof \TYPO3\CMS\Core\Error\Http\PageNotFoundException) {
$GLOBALS['TSFE']->pageNotFoundAndExit($this->entityNotFoundMessage);
}
// $GLOBALS['TSFE']->pageNotFoundAndExit has not been called, so the exception is of unknown type.
\VendorName\ExtensionName\Logger\ExceptionLogger::log($exception, $this->request->getControllerExtensionKey(), \VendorName\ExtensionName\Logger\ExceptionLogger::SEVERITY_FATAL_ERROR);
// If the plugin is configured to do so, we call the page-unavailable handler.
if (isset($this->settings['usePageUnavailableHandler']) && $this->settings['usePageUnavailableHandler']) {
$GLOBALS['TSFE']->pageUnavailableAndExit($this->unknownErrorMessage, 'HTTP/1.1 500 Internal Server Error');
}
// Else we append the error message to the response. This causes the error message to be displayed inside the normal page layout. WARNING: the plugins output may gets cached.
if ($this->response instanceof \TYPO3\CMS\Extbase\Mvc\Web\Response) {
$this->response->setStatus(500);
}
$this->response->appendContent($this->unknownErrorMessage);
}
}
}
这里有一篇文章对此进行了解释。
然而,大多数关于 TYPO3 编程的文章都是德语的 ;-)
你隐含地问了 2 个问题:
- 如何在我的代码中正确抛出异常?
我认为,你所做的是正确的:只需使用 PHP \Exception 或从 \Exception:
继承的合适异常
throw new \UnexpectedValueException('Invalid data');
- 抛出异常后,如何查看更多信息?
这已经回答得很好:
在开发系统上:
- 设置配置预设“调试”
- 在起始页添加 TypoScript:
config.contentObjectExceptionHandler = 0
见Error and ExceptionHandling Example
在生产系统上:
您通常不想在前端看到完整的堆栈跟踪。这就是为什么 config.contentObjectExceptionHandler
通常设置为默认值,它只显示 Oops,发生错误!代码:呈现页面上的 20160721101726b5339896。使用此代码,您可以查看日志(是否记录了内容以及记录的内容始终取决于日志系统的配置):
- sys_log : 查看后端的“日志”
- 日志文件:var/logs/*.log(参见 Logging with TYPO3)。在旧版本上可能是 typo3temp/logs,在非 Composer 系统上可能是 typo3temp/var/logs/。
在 Extbase 扩展中,可能需要通知用户错误或异常。
在我的例子中,我必须解析来自潜在不良来源的一些数据。因此扩展程序必须验证此数据。而如果数据无效,则需要抛出一个异常,然后由TYPO3处理。
但是,我只能找到有关异常和错误处理程序如何工作的信息,但找不到有关如何从扩展内部正确抛出异常的信息。
那么从 Extbase 扩展内部抛出异常的预期方法是什么?
预期结果
如果我产生语法错误,TYPO3 会显示类似如下的消息:
这就是我所期望的 正确 抛出错误或异常的样子。
我试过的
编辑:我尝试抛出这样的错误:
throw new \Exception('Invalid data');
但是,所有的前端显示都是
Oops, an error occurred! Code: 20160721101726b5339896
产生错误的另一种可能方式:
$GLOBALS['TSFE']->pageNotFoundAndExit('Invalid data');
但是,这显示页面未找到错误而不是预期的异常。
namespace VendorName\ExtensionName\Controller;
abstract class ActionController extends \TYPO3\CMS\Extbase\Mvc\Controller\ActionController {
/**
* @var string
*/
protected $entityNotFoundMessage = 'The requested entity could not be found.';
/**
* @var string
*/
protected $unknownErrorMessage = 'An unknown error occurred. The wild monkey horde in our basement will try to fix this as soon as possible.';
/**
* @param \TYPO3\CMS\Extbase\Mvc\RequestInterface $request
* @param \TYPO3\CMS\Extbase\Mvc\ResponseInterface $response
* @return void
* @throws \Exception
* @override \TYPO3\CMS\Extbase\Mvc\Controller\ActionController
*/
public function processRequest(\TYPO3\CMS\Extbase\Mvc\RequestInterface $request, \TYPO3\CMS\Extbase\Mvc\ResponseInterface $response) {
try {
parent::processRequest($request, $response);
}
catch(\Exception $exception) {
// If the property mapper did throw a \TYPO3\CMS\Extbase\Property\Exception, because it was unable to find the requested entity, call the page-not-found handler.
$previousException = $exception->getPrevious();
if (($exception instanceof \TYPO3\CMS\Extbase\Property\Exception) && (($previousException instanceof \TYPO3\CMS\Extbase\Property\Exception\TargetNotFoundException) || ($previousException instanceof \TYPO3\CMS\Extbase\Property\Exception\InvalidSourceException))) {
$GLOBALS['TSFE']->pageNotFoundAndExit($this->entityNotFoundMessage);
}
throw $exception;
}
}
/**
* @return void
* @override \TYPO3\CMS\Extbase\Mvc\Controller\ActionController
*/
protected function callActionMethod() {
try {
parent::callActionMethod();
}
catch(\Exception $exception) {
// This enables you to trigger the call of TYPO3s page-not-found handler by throwing \TYPO3\CMS\Core\Error\Http\PageNotFoundException
if ($exception instanceof \TYPO3\CMS\Core\Error\Http\PageNotFoundException) {
$GLOBALS['TSFE']->pageNotFoundAndExit($this->entityNotFoundMessage);
}
// $GLOBALS['TSFE']->pageNotFoundAndExit has not been called, so the exception is of unknown type.
\VendorName\ExtensionName\Logger\ExceptionLogger::log($exception, $this->request->getControllerExtensionKey(), \VendorName\ExtensionName\Logger\ExceptionLogger::SEVERITY_FATAL_ERROR);
// If the plugin is configured to do so, we call the page-unavailable handler.
if (isset($this->settings['usePageUnavailableHandler']) && $this->settings['usePageUnavailableHandler']) {
$GLOBALS['TSFE']->pageUnavailableAndExit($this->unknownErrorMessage, 'HTTP/1.1 500 Internal Server Error');
}
// Else we append the error message to the response. This causes the error message to be displayed inside the normal page layout. WARNING: the plugins output may gets cached.
if ($this->response instanceof \TYPO3\CMS\Extbase\Mvc\Web\Response) {
$this->response->setStatus(500);
}
$this->response->appendContent($this->unknownErrorMessage);
}
}
}
这里有一篇文章对此进行了解释。 然而,大多数关于 TYPO3 编程的文章都是德语的 ;-)
你隐含地问了 2 个问题:
- 如何在我的代码中正确抛出异常?
我认为,你所做的是正确的:只需使用 PHP \Exception 或从 \Exception:
继承的合适异常throw new \UnexpectedValueException('Invalid data');
- 抛出异常后,如何查看更多信息?
这已经回答得很好:
在开发系统上:
- 设置配置预设“调试”
- 在起始页添加 TypoScript:
config.contentObjectExceptionHandler = 0
见Error and ExceptionHandling Example
在生产系统上:
您通常不想在前端看到完整的堆栈跟踪。这就是为什么 config.contentObjectExceptionHandler
通常设置为默认值,它只显示 Oops,发生错误!代码:呈现页面上的 20160721101726b5339896。使用此代码,您可以查看日志(是否记录了内容以及记录的内容始终取决于日志系统的配置):
- sys_log : 查看后端的“日志”
- 日志文件:var/logs/*.log(参见 Logging with TYPO3)。在旧版本上可能是 typo3temp/logs,在非 Composer 系统上可能是 typo3temp/var/logs/。