如何在扩展中抛出异常?

Posted

技术标签:

【中文标题】如何在扩展中抛出异常?【英文标题】:How to throw an exception in your Extension? 【发布时间】:2016-11-24 16:04:39 【问题描述】:

在 Extbase 扩展中,可能需要通知用户错误或异常。

在我的情况下,我必须解析来自潜在不良来源的一些数据。所以扩展必须验证这些数据。并且如果数据无效,则需要抛出异常,然后TYPO3可以处理。

但是,我只能找到有关异常和错误处理程序如何工作的信息,但找不到有关如何从扩展内部正确抛出异常的信息。

那么从 Extbase 扩展内部抛出异常的预期方法是什么?

预期结果

如果我产生语法错误,TYPO3 会显示类似以下的消息: (取自the core API reference。)

这就是我希望正确抛出的错误或异常的样子。

我尝试了什么

编辑:我尝试抛出这样的错误:

throw new \Exception('Invalid data');

但是,所有的前端显示都是

糟糕,发生错误!代码:20160721101726b5339896

产生错误的另一种可能方式:

$GLOBALS['TSFE']->pageNotFoundAndExit('Invalid data');

但是,这显示了一个页面未找到错误,而不是预期的异常。

【问题讨论】:

为什么不使用旧的php.net/manual/de/exception.construct.php 或异常处理插件? @cptnk 对不起,我应该更详细的。已经试过了,没有给出预期的结果。附加我的问题。 啊,您可能只是在 LocalConfiguration 中设置了 displayErrors 来隐藏错误消息并将它们存储在 error.log 中。现在这就是你可能想要的行为。不如使用 flashmessanger 来代替? 但是正如我所期望的那样显示语法错误,如屏幕截图所示。 语法错误和退出是不同的。如果您的 PHP 检测到语法错误,它会在该点停止并打印错误消息。根据发生这种情况的时间,您可能已经拥有来自typo3的“错误样式”,但您可能从未接近处理错误的实际typo3应用程序。 【参考方案1】:
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 编程的文章一样,都是德语的 ;-)

http://nerdcenter.de/extbase-fehlerbehandlung/

【讨论】:

谢谢。如果您可以在答案中包含链接中的实际解决方案,这可能会很有用,尤其是在文章不是英文的情况下。作为对未来的提示,您应始终尝试将来自外部来源的相关信息与链接一起发布,以使您的答案更有用。 另外,我尝试了你的方式,使用$GLOBALS['TSFE']->pageNotFoundAndExit('Invalid data');。但它仍然没有导致我预期的行为。查看我的问题的编辑,了解我在抛出异常时会发生什么。 这可能是因为您在生产模式下使用 TYPO3 而不是在开发模式下。您必须检查您的 htaccess 如何执行此操作。在这里您可以找到如何编辑您的 .htaccess 以触发开发模式。 docs.typo3.org/typo3cms/extensions/powermail/ForAdministrators/… 在 LocalConfiguration 中,我启用了前端和后端的调试。这似乎可行,因为扩展程序中的常规语法错误会像屏幕截图一样显示。 您能否尝试将其添加到您的 .htaccess 文件并清除整个缓存并重试,应该可以正常工作。【参考方案2】:

你含蓄地问了两个问题:

1。如何在我的代码中正确抛出异常?

我认为,这是正确的,你所做的:只需使用 PHP \Exception 或从 \Exception 继承的合适异常:

throw new \UnexpectedValueException('Invalid data');

2。抛出异常后,如何查看更多信息?

这已经得到了很好的回答:https://***.com/a/34067853/2444812

在开发系统上:

设置配置预设“调试” 在起始页上添加 TypoScript:config.contentObjectExceptionHandler = 0

见Error and ExceptionHandling Example

在生产系统上:

您通常不希望在前端看到完整的堆栈跟踪。这就是为什么config.contentObjectExceptionHandler 通常设置为默认值,它只显示糟糕,发生错误!代码:20160721101726b5339896 在呈现的页面上。使用此代码,您可以查看日志(是否记录了内容以及记录的内容始终取决于日志记录系统的配置):

sys_log : 查看后端的“日志” 日志文件:var/logs/*.log(参见Logging with TYPO3)。在旧版本上可能是typo3temp/logs,在非Composer 系统上可能是typo3temp/var/logs/。

【讨论】:

以上是关于如何在扩展中抛出异常?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Symfony2 中抛出 403 异常?

如何捕获ctypes中抛出的异常?

如何捕获 node_modules 中抛出的异常

在 Zend Framework 应用程序中从模型/视图/控制器中抛出异常

为啥在析构函数中抛出异常时不调用重载删除?

Objective-C 在静态库中抛出异常。如何使用该库从程序中捕获异常?