mirror of
https://github.com/Combodo/iTop.git
synced 2026-02-13 07:24:13 +01:00
N°3522 Handle twig errors nicely
Revert what was done in c5021721 : I then added a panel to be rendered instead of throwing an Exception. This was done because the exception was displayed in a blank page... But this was caused simply by a missing `use Exception` !!
So now we're back at throwing an exception, so that the standard mechanism for throwing the error page is triggered.
Handling Twig recursion is mandatory, and done in the beginning of the \Combodo\iTop\Application\TwigBase\Twig\TwigHelper::RenderTemplate catch block to avoid adding on each stack level a useless exception.
This commit is contained in:
17
application/exceptions/CoreTemplateException.php
Normal file
17
application/exceptions/CoreTemplateException.php
Normal file
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* @since 3.0.0 N°3522
|
||||
*/
|
||||
class CoreTemplateException extends CoreException
|
||||
{
|
||||
public function __construct(Exception $oTwigException, string $sTemplatePath)
|
||||
{
|
||||
$sMessage = "Twig Exception when rendering '$sTemplatePath' : ".$oTwigException->getMessage();
|
||||
parent::__construct($sMessage, null, '', $oTwigException);
|
||||
}
|
||||
}
|
||||
@@ -460,7 +460,6 @@ Dict::Add('EN US', 'English', 'English', array(
|
||||
'UI:Error:MaintenanceMode' => 'Application is currently in maintenance',
|
||||
'UI:Error:MaintenanceTitle' => 'Maintenance',
|
||||
'UI:Error:InvalidToken' => 'Error: the requested operation has already been performed (CSRF token not found)',
|
||||
'UI:Error:TemplateRendering' => 'Cannot render template',
|
||||
|
||||
'UI:GroupBy:Count' => 'Count',
|
||||
'UI:GroupBy:Count+' => 'Number of elements',
|
||||
|
||||
@@ -456,7 +456,6 @@ Dict::Add('FR FR', 'French', 'Français', array(
|
||||
'UI:Error:MaintenanceMode' => 'L\'application est en maintenance',
|
||||
'UI:Error:MaintenanceTitle' => 'Maintenance',
|
||||
'UI:Error:InvalidToken' => 'Erreur: l\'opération a déjà été effectuée (CSRF token not found)',
|
||||
'UI:Error:TemplateRendering' => 'Impossible de rendre le template',
|
||||
|
||||
'UI:GroupBy:Count' => 'Nombre',
|
||||
'UI:GroupBy:Count+' => 'Nombre d\'éléments',
|
||||
|
||||
@@ -345,6 +345,7 @@ return array(
|
||||
'CoreOqlMultipleResultsForbiddenException' => $baseDir . '/application/exceptions/oql/CoreOqlMultipleResultsForbiddenException.php',
|
||||
'CorePortalInvalidActionRuleException' => $baseDir . '/application/exceptions/CorePortalInvalidActionRuleException.php',
|
||||
'CoreServices' => $baseDir . '/core/restservices.class.inc.php',
|
||||
'CoreTemplateException' => $baseDir . '/application/exceptions/CoreTemplateException.php',
|
||||
'CoreUnexpectedValue' => $baseDir . '/application/exceptions/CoreUnexpectedValue.php',
|
||||
'CoreWarning' => $baseDir . '/application/exceptions/CoreWarning.php',
|
||||
'CryptEngine' => $baseDir . '/core/simplecrypt.class.inc.php',
|
||||
|
||||
@@ -575,6 +575,7 @@ class ComposerStaticInit0018331147de7601e7552f7da8e3bb8b
|
||||
'CoreOqlMultipleResultsForbiddenException' => __DIR__ . '/../..' . '/application/exceptions/oql/CoreOqlMultipleResultsForbiddenException.php',
|
||||
'CorePortalInvalidActionRuleException' => __DIR__ . '/../..' . '/application/exceptions/CorePortalInvalidActionRuleException.php',
|
||||
'CoreServices' => __DIR__ . '/../..' . '/core/restservices.class.inc.php',
|
||||
'CoreTemplateException' => __DIR__ . '/../..' . '/application/exceptions/CoreTemplateException.php',
|
||||
'CoreUnexpectedValue' => __DIR__ . '/../..' . '/application/exceptions/CoreUnexpectedValue.php',
|
||||
'CoreWarning' => __DIR__ . '/../..' . '/application/exceptions/CoreWarning.php',
|
||||
'CryptEngine' => __DIR__ . '/../..' . '/core/simplecrypt.class.inc.php',
|
||||
|
||||
@@ -7,9 +7,7 @@
|
||||
namespace Combodo\iTop\Application\TwigBase\Twig;
|
||||
|
||||
use Combodo\iTop\Application\TwigBase\UI\UIBlockExtension;
|
||||
use Combodo\iTop\Application\UI\Base\Component\Alert\AlertUIBlockFactory;
|
||||
use Combodo\iTop\Renderer\BlockRenderer;
|
||||
use Dict;
|
||||
use CoreTemplateException;
|
||||
use IssueLog;
|
||||
use Twig\Environment;
|
||||
use Twig\Error\Error;
|
||||
@@ -116,53 +114,37 @@ class TwigHelper
|
||||
* @param bool $bLogMissingFile
|
||||
*
|
||||
* @return string
|
||||
* @throws \Twig\Error\RuntimeError
|
||||
* @throws \Twig\Error\SyntaxError
|
||||
* @throws \Exception
|
||||
* @throws \CoreTemplateException
|
||||
*/
|
||||
public static function RenderTemplate(Environment $oTwig, array $aParams, string $sName, string $sTemplateFileExtension = self::DEFAULT_FILE_TYPE, bool $bLogMissingFile = true): string
|
||||
{
|
||||
try {
|
||||
return $oTwig->render($sName.'.'.$sTemplateFileExtension.'.twig', $aParams);
|
||||
} catch (Error $e) {
|
||||
$sPath = '';
|
||||
if ($e->getSourceContext()) {
|
||||
$sPath = utils::LocalPath($e->getSourceContext()->getPath()).' ('.$e->getLine().') - ';
|
||||
}
|
||||
catch (Error $oTwigException) {
|
||||
$oTwigPreviousException = $oTwigException->getPrevious();
|
||||
if (!is_null(($oTwigPreviousException)) && ($oTwigPreviousException instanceof CoreTemplateException)) {
|
||||
// handles recursive calls : if we're here, an exception was already raised in a child template !
|
||||
throw $oTwigPreviousException;
|
||||
}
|
||||
$sMessage = $sPath.$e->getMessage();
|
||||
|
||||
if (strpos($e->getMessage(), 'Unable to find template') === false) {
|
||||
IssueLog::Error($sMessage);
|
||||
$sPath = '';
|
||||
if ($oTwigException->getSourceContext()) {
|
||||
$sPath = utils::LocalPath($oTwigException->getSourceContext()->getPath()).' ('.$oTwigException->getLine().') - ';
|
||||
}
|
||||
|
||||
return static::GenerateEndUserError(Dict::S('UI:Error:TemplateRendering'), $sMessage);
|
||||
if (strpos($oTwigException->getMessage(), 'Unable to find template') === false) {
|
||||
//TODO handle ajax ??
|
||||
// this will trigger error page, and will log to error.log !
|
||||
throw new CoreTemplateException($oTwigException, $sPath);
|
||||
}
|
||||
|
||||
if ($bLogMissingFile) {
|
||||
IssueLog::Debug($sMessage);
|
||||
$sLogMessageMissingFile = "Twig : missing file '$sPath' : ".$oTwigException->getMessage();
|
||||
IssueLog::Debug($sLogMessageMissingFile);
|
||||
}
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sTitle
|
||||
* @param string $sMessage
|
||||
*
|
||||
* @return string error panel markup
|
||||
*
|
||||
* @throws \ReflectionException
|
||||
* @throws \Twig\Error\LoaderError
|
||||
* @throws \Twig\Error\RuntimeError
|
||||
* @throws \Twig\Error\SyntaxError
|
||||
* @since 3.0.0 N°3522 method creation
|
||||
*/
|
||||
protected static function GenerateEndUserError(string $sTitle, string $sMessage): string
|
||||
{
|
||||
$oAlert = AlertUIBlockFactory::MakeForFailure($sTitle, $sMessage)
|
||||
->SetIsClosable(false)
|
||||
->SetIsCollapsible(false); // not rendering JS so...
|
||||
|
||||
return BlockRenderer::RenderBlockTemplates($oAlert);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user