craftcms / cms

Build bespoke content experiences with Craft.
https://craftcms.com
Other
3.2k stars 617 forks source link

[4.x]: Illegal GraphQL mutation to date field (with enable timezone) is uncaught and breaks the entry #13893

Closed robinbeatty closed 7 months ago

robinbeatty commented 8 months ago

What happened?

On a Date field that has date and time enabled, with 'Allow authors to set timezone' selected – if we send an atom date down the pipe via GraphQL to this field it's uncaught during the mutation (no errors returned in the response) but when entry is loaded by the CP it breaks giving the trace below. Expect we should get an error in the response (and ideally a hint!).

Btw what format should the string be that this field should expect?

If I remove the timezone flag from the field with the illegal value (one that didn't define the timezone) in the db, the entry loads. So expect should be something to validate it before it lands in the db?

IntlException: datefmt_create: No such time zone: '+00:00': U_ILLEGAL_ARGUMENT_ERROR in /var/www/html/vendor/yiisoft/yii2/i18n/Formatter.php:809
Stack trace:
#0 /var/www/html/vendor/yiisoft/yii2/i18n/Formatter.php(809): IntlDateFormatter->__construct('en-GB', -1, -1, '+00:00', NULL, 'dd/MM/y')
#1 /var/www/html/vendor/yiisoft/yii2/i18n/Formatter.php(658): yii\i18n\Formatter->formatDateTimeValue(Object(DateTime), 'dd/MM/y', 'date')
#2 /var/www/html/vendor/craftcms/cms/src/i18n/Formatter.php(87): yii\i18n\Formatter->asDate(Object(DateTime), 'dd/MM/y')
#3 /var/www/html/vendor/craftcms/cms/src/web/twig/Extension.php(970): craft\i18n\Formatter->asDate(Object(DateTime), 'dd/MM/y')
#4 /var/www/html/storage/runtime/compiled_templates/2b/2b4d4d2ebdb7461b04346d967ae51172.php(106): craft\web\twig\Extension->dateFilter(Object(craft\web\twig\Environment), Object(DateTime), 'short', false)
#5 /var/www/html/vendor/twig/twig/src/Template.php(394): __TwigTemplate_d89d09cb089d8d28923a64daed84806a->doDisplay(Array, Array)
#6 /var/www/html/vendor/twig/twig/src/Template.php(367): Twig\Template->displayWithErrorHandling(Array, Array)
#7 /var/www/html/vendor/twig/twig/src/Template.php(379): Twig\Template->display(Array)
#8 /var/www/html/vendor/twig/twig/src/TemplateWrapper.php(40): Twig\Template->render(Array, Array)
#9 /var/www/html/vendor/twig/twig/src/Environment.php(277): Twig\TemplateWrapper->render(Array)
#10 /var/www/html/vendor/craftcms/cms/src/web/View.php(482): Twig\Environment->render('_includes/forms...', Array)
#11 /var/www/html/vendor/craftcms/cms/src/fields/Date.php(271): craft\web\View->renderTemplate('_includes/forms...', Array)
#12 /var/www/html/vendor/craftcms/cms/src/base/Field.php(503): craft\fields\Date->inputHtml(Object(DateTime), Object(craft\elements\MatrixBlock))
#13 /var/www/html/vendor/craftcms/cms/src/fieldlayoutelements/CustomField.php(273): craft\base\Field->getInputHtml(Object(DateTime), Object(craft\elements\MatrixBlock))
#14 /var/www/html/vendor/craftcms/cms/src/fieldlayoutelements/BaseField.php(235): craft\fieldlayoutelements\CustomField->inputHtml(Object(craft\elements\MatrixBlock), false)
#15 /var/www/html/vendor/craftcms/cms/src/fieldlayoutelements/CustomField.php(222): craft\fieldlayoutelements\BaseField->formHtml(Object(craft\elements\MatrixBlock), false)
#16 /var/www/html/vendor/craftcms/cms/src/web/View.php(1669): craft\fieldlayoutelements\CustomField->craft\fieldlayoutelements\{closure}()
#17 /var/www/html/vendor/craftcms/cms/src/fieldlayoutelements/CustomField.php(223): craft\web\View->namespaceInputs(Object(Closure), 'fields')
#18 /var/www/html/vendor/craftcms/cms/src/models/FieldLayout.php(738): craft\fieldlayoutelements\CustomField->formHtml(Object(craft\elements\MatrixBlock), false)
#19 /var/www/html/vendor/craftcms/cms/src/web/View.php(1663): craft\models\FieldLayout->craft\models\{closure}()
#20 /var/www/html/vendor/craftcms/cms/src/models/FieldLayout.php(737): craft\web\View->namespaceInputs(Object(Closure), NULL)
#21 /var/www/html/vendor/twig/twig/src/Extension/CoreExtension.php(1607): craft\models\FieldLayout->createForm(Object(craft\elements\MatrixBlock), false)
#22 /var/www/html/vendor/craftcms/cms/src/helpers/Template.php(129): twig_get_attribute(Object(craft\web\twig\Environment), Object(Twig\Source), Object(craft\models\FieldLayout), 'createForm', Array, 'method', false, false)
#23 /var/www/html/storage/runtime/compiled_templates/d0/d029139aca8a44422ddfecb754aa5a71.php(293): craft\helpers\Template::attribute(Object(craft\web\twig\Environment), Object(Twig\Source), Object(craft\models\FieldLayout), 'createForm', Array, 'method')
#24 /var/www/html/vendor/twig/twig/src/Template.php(394): __TwigTemplate_71ba57f6139d9dd19c2caffecc938353->doDisplay(Array, Array)
#25 /var/www/html/vendor/twig/twig/src/Template.php(367): Twig\Template->displayWithErrorHandling(Array, Array)
#26 /var/www/html/vendor/twig/twig/src/Template.php(379): Twig\Template->display(Array)
#27 /var/www/html/vendor/twig/twig/src/TemplateWrapper.php(40): Twig\Template->render(Array, Array)
#28 /var/www/html/vendor/twig/twig/src/Environment.php(277): Twig\TemplateWrapper->render(Array)
#29 /var/www/html/vendor/craftcms/cms/src/web/View.php(482): Twig\Environment->render('_components/fie...', Array)
#30 /var/www/html/vendor/craftcms/cms/src/fields/Matrix.php(775): craft\web\View->renderTemplate('_components/fie...', Array)
#31 /var/www/html/vendor/craftcms/cms/src/base/Field.php(503): craft\fields\Matrix->inputHtml(Array, Object(craft\elements\Entry))
#32 /var/www/html/vendor/craftcms/cms/src/fieldlayoutelements/CustomField.php(273): craft\base\Field->getInputHtml(Object(craft\elements\db\MatrixBlockQuery), Object(craft\elements\Entry))
#33 /var/www/html/vendor/craftcms/cms/src/fieldlayoutelements/BaseField.php(235): craft\fieldlayoutelements\CustomField->inputHtml(Object(craft\elements\Entry), false)
#34 /var/www/html/vendor/craftcms/cms/src/fieldlayoutelements/CustomField.php(222): craft\fieldlayoutelements\BaseField->formHtml(Object(craft\elements\Entry), false)
#35 /var/www/html/vendor/craftcms/cms/src/web/View.php(1669): craft\fieldlayoutelements\CustomField->craft\fieldlayoutelements\{closure}()
#36 /var/www/html/vendor/craftcms/cms/src/fieldlayoutelements/CustomField.php(223): craft\web\View->namespaceInputs(Object(Closure), 'fields')
#37 /var/www/html/vendor/craftcms/cms/src/models/FieldLayout.php(738): craft\fieldlayoutelements\CustomField->formHtml(Object(craft\elements\Entry), false)
#38 /var/www/html/vendor/craftcms/cms/src/web/View.php(1663): craft\models\FieldLayout->craft\models\{closure}()
#39 /var/www/html/vendor/craftcms/cms/src/models/FieldLayout.php(737): craft\web\View->namespaceInputs(Object(Closure), NULL)
#40 /var/www/html/vendor/craftcms/cms/src/controllers/ElementsController.php(810): craft\models\FieldLayout->createForm(Object(craft\elements\Entry), false, Array)
#41 /var/www/html/vendor/craftcms/cms/src/controllers/ElementsController.php(446): craft\controllers\ElementsController->_prepareEditor(Object(craft\elements\Entry), false, true, Object(craft\web\Response), 'main-form', Object(Closure), Object(Closure), Object(Closure))
#42 [internal function]: craft\controllers\ElementsController->craft\controllers\{closure}(Object(craft\web\Response), 'main-form')
#43 /var/www/html/vendor/craftcms/cms/src/web/CpScreenResponseFormatter.php(121): call_user_func(Object(Closure), Object(craft\web\Response), 'main-form')
#44 /var/www/html/vendor/craftcms/cms/src/web/CpScreenResponseFormatter.php(49): craft\web\CpScreenResponseFormatter->_formatTemplate(Object(craft\web\Response), Object(craft\web\CpScreenResponseBehavior))
#45 /var/www/html/vendor/yiisoft/yii2/web/Response.php(1100): craft\web\CpScreenResponseFormatter->format(Object(craft\web\Response))
#46 /var/www/html/vendor/craftcms/cms/src/web/Response.php(337): yii\web\Response->prepare()
#47 /var/www/html/vendor/yiisoft/yii2/web/Response.php(340): craft\web\Response->prepare()
#48 /var/www/html/vendor/yiisoft/yii2/base/Application.php(390): yii\web\Response->send()
#49 /var/www/html/web/index.php(12): yii\base\Application->run()
#50 {main}

Craft CMS version

4.5.9

PHP version

8.1

Operating system and version

No response

Database type and version

MariaDB 10.4

Image driver and version

No response

Installed plugins and versions

-

i-just commented 8 months ago

Hi, thanks for getting in touch!

GraphQL doesn’t return an error when you use an atom date because it understands it correctly. If you were to pass an invalid atom date string, you’d get an error. The problem starts once the date is retrieved again in the Control Panel. IntlDateFormatter doesn’t do particularly well with numerical timezones (e.g. +00:00). At the moment, if you were to use something like: 2023-11-03 08:00:00 Europe/Berlin as your string date format, that would work great.

We’ll discuss this further internally.

brandonkelly commented 7 months ago

Craft 4.5.11 is out now, with improved support for mutating Date fields with “Show Time Zone” enabled. Now you can use either one of these formats:

If either of those are used, the time zone will be remembered in the UI.