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:
Pierre Goiffon
2021-03-11 11:26:06 +01:00
parent 4932a2cfbd
commit e49b0db58d
6 changed files with 37 additions and 38 deletions

View 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);
}
}

View File

@@ -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',

View File

@@ -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',

View File

@@ -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',

View File

@@ -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',

View File

@@ -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);
}
}