Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improved structure for error message generation in configuration pages #29494

Open
wants to merge 29 commits into
base: develop
Choose a base branch
from

Conversation

JevgenijVisockij
Copy link
Contributor

@JevgenijVisockij JevgenijVisockij commented Aug 31, 2022

Questions Answers
Branch? develop
Description? Refactors error generation for configuration pages. With changes error system is more streamlined allowing for pages with same error reuse the code rather then duplicating it, as well as moving code from controllers to separate factories. Also added label provider which takes label from the form, rather then having to duplicate label somewhere else.
Type? refacto
Category? BO
BC breaks? no
Deprecations? no
Fixed ticket?
Related PRs #20243 same was done in invoice PR, but separating this, so it hopefully get's faster and is part of 8.0
How to test? Test that administration page throws errors correctly, when entering wrong info.

@JevgenijVisockij JevgenijVisockij requested a review from a team as a code owner August 31, 2022 14:47
@prestonBot prestonBot added the Refactoring Type: Refactoring label Aug 31, 2022
use PrestaShop\PrestaShop\Core\Form\ErrorMessage\ConfigurationErrorInterface;

/** Interface for configuration error factories which are responsible for returning error messages for configuration errors */
interface ConfigurationErrorFactoryInterface
Copy link
Contributor

@zuk3975 zuk3975 Sep 1, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

seems more like a message provider.
"ConfigurationErrorMessageProvider".

then it will be less confusing considering we also have src/PrestaShopBundle/Form/ErrorMessage/Factory/ConfigurationErrorFactory.php (because now its named the same, but is different service)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I guess the name make sense, thanks!

foreach ($view->children as $child) {
if (isset($child->vars['name']) && $fieldName === $child->vars['name']) {
if (!isset($child->vars['label'])) {
throw new FieldLabelNotFoundException(
Copy link
Contributor

@zuk3975 zuk3975 Sep 1, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we really need to throw error if label isn't there?
I think It is legit that some fields doesn't have labels, so what happens if such field is violated? then everything will probably break, no?

Maybe we should fallback to field name when label is not set?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, I guess you are right, I will just return fieldName, probably better then breaking everything, since then only display will be a worse in worst case.

@prestonBot prestonBot added the develop Branch label Sep 1, 2022
zuk3975
zuk3975 previously approved these changes Sep 12, 2022
@JevgenijVisockij JevgenijVisockij changed the base branch from develop to 8.0.x September 15, 2022 08:26
@JevgenijVisockij JevgenijVisockij dismissed zuk3975’s stale review September 15, 2022 08:26

The base branch was changed.

@JevgenijVisockij JevgenijVisockij changed the base branch from 8.0.x to develop September 15, 2022 08:32
@JevgenijVisockij
Copy link
Contributor Author

Delayed until 9.0

Copy link
Contributor

@jolelievre jolelievre left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As we discussed we'll try and minimize the breaking changes here so:

  • we don't remove the initial error class, nor the collection and its associated exception, but we deprecate them
  • create new Error classes (with your interface) along with a new collection and associated exception

In the end, the only BC is that the validation method triggers a new kind of exception

@prestonBot prestonBot added the Waiting for wording Status: action required, waiting for wording label Oct 17, 2022
@@ -35,10 +35,6 @@
*/
final class FormDataProvider implements FormDataProviderInterface
{
public const ERROR_NOT_NUMERIC_OR_LOWER_THAN_ZERO = 1;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

are these constants already part of a release ? if yes that is a BC Break

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are right, it's BC break will add them back and depricate

@@ -31,6 +31,7 @@
use PrestaShop\PrestaShop\Core\Domain\Exception\DomainException;
use Throwable;

/** @deprecated and will be removed in 9.0 */
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can call @trigger_error before the class to make sure in will appear in the logs.

@@ -0,0 +1,27 @@
services:
_defaults:
public: true
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think these services don't need to be public

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As far as I see every single yml file in PS has services as public, I don't remember the exact reason, but I know at least in modules sometimes things don't work if you don't make services public.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We are starting to make private services to optimize the container, I think it is better to stop adding public service, il will ease the work in the future.

Also, you can create your new services with the FQCN now :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alright that makes sense. Implemented FQCN.

use PrestaShopBundle\Entity\Repository\LangRepository;
use PrestaShopBundle\Form\Admin\Configure\AdvancedParameters\Administration\GeneralDataProvider;
use PrestaShopBundle\Form\ErrorMessage\Factory\AdministrationConfigurationErrorMessageProvider;
use Symfony\Component\Translation\Translator;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wrong namespace here

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You mean the translator? Changed it to interface since that's what class is using

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

he one from Symfony\Contracts should be used instead.
#30496

/**
* @return int|null
*/
public function getLanguageId(): ?int
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where is this function used ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's needed in the future, but after thinking about it yeah it's probably not needed now. Removed it.

/**
* @return int|null
*/
public function getLanguageId(): ?int;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think the interface should have this method. An error does not have to be aware of the context locale IMO.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It meant not for the context locale, but for when there is mulitlang field, so we know in which language error happened. But yeah it's not needed in interface errors needing that can use the function without it being in interface.

Comment on lines 49 to 50
* AdministrationConfigurationError constructor.
*
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* AdministrationConfigurationError constructor.
*

zuk3975
zuk3975 previously approved these changes Nov 29, 2022
use PrestaShop\PrestaShop\Core\Form\ErrorMessage\ConfigurationErrorInterface;
use PrestaShop\PrestaShop\Core\Form\ErrorMessage\Factory\ConfigurationErrorMessageProviderInterface;
use PrestaShopBundle\Entity\Repository\LangRepository;
use Symfony\Component\Translation\TranslatorInterface;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The translator should come from Symfony/Contracts (in mutliple places)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed those

@@ -0,0 +1,27 @@
services:
_defaults:
public: true
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We are starting to make private services to optimize the container, I think it is better to stop adding public service, il will ease the work in the future.

Also, you can create your new services with the FQCN now :)

@@ -0,0 +1,23 @@
services:
PrestaShopBundle\Form\ErrorMessage\LabelProvider:
class: PrestaShopBundle\Form\ErrorMessage\LabelProvider
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When using FQCN, the class: is not needed anymore, as it should follow the namespace and symfony finds it. (on the other hand when the service have multiple implementations, then it is supposed to be defined using snake_case and requires the class: attribute)

Suggested change
class: PrestaShopBundle\Form\ErrorMessage\LabelProvider

check other definitions too.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changes those, thanks!

zuk3975
zuk3975 previously approved these changes Dec 13, 2022
} catch (DataProviderException $e) {
$this->flashErrors($this->getErrorMessages($e->getInvalidConfigurationDataErrors()));
} catch (FormDataProviderException $e) {
$errorMessageFactory = $this->get('prestashop.form.error_message.configuration_error_factory');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think for new service call, we should fit with https://github.com/PrestaShop/ADR/blob/master/0019-FQCN-Autowiring.md. You probably should create FQCN version of prestashop.form.error_message.configuration_error_factory and use it here.

lartist
lartist previously approved these changes Jan 17, 2023
@zuk3975 zuk3975 added this to the 8.1.0 milestone Jan 18, 2023
zuk3975
zuk3975 previously approved these changes Jan 18, 2023
@zuk3975
Copy link
Contributor

zuk3975 commented Jan 18, 2023

ping @PrestaShop/wording-managers to approve the wording before we go to QA

private function getDefaultErrorMessage(string $label): string
{
return $this->translator->trans(
'%s is invalid.',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there more info on the nature of the error? Telling the user "x is invalid" isn't going to help them 🤔

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This message is used only for the fallback case, the idea here is to try and match any Exception with the appropriate error message, that is actually what was done in the previous provider classes like CommonConfigurationErrorMessageProvider on a case by case based on the exception

But in case no specific case was handled for an unexpected error we still need to display some default message, it will lack details until the error use case is properly handled for the specific error case.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, ok - I see. Thank you

switch ($error->getErrorCode()) {
case AdministrationConfigurationError::ERROR_COOKIE_LIFETIME_MAX_VALUE_EXCEEDED:
return $this->translator->trans(
'%s is invalid. Please enter an integer lower than %s.',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
'%s is invalid. Please enter an integer lower than %s.',
'Exceeds the maximum lifetime value of a cookie. Please enter an integer lower than %s.',

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't it be better to add a help text to tell the user what the max lifetime value of a cookie is?
So that we don't have to tell them "No, the value you entered is too high" after they're done typing it in.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually @l-delin the message here uses a placeholder %s is invalid the %s part is replaced by the variable $label which will automatically provide the name of the field from the form (which is also translated independently). So the interest here is to use a single wording with placeholder for any label/field

Copy link
Contributor

@l-delin l-delin Jan 19, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alright, makes sense. Then, feel free to dismiss this edit :-)

@JevgenijVisockij JevgenijVisockij dismissed stale reviews from zuk3975 and lartist via ed8990a May 31, 2023 09:25
@JevgenijVisockij
Copy link
Contributor Author

The SameSite=None attribute is only available in a secure context (HTTPS).

Fixed thie issue

@prestashop-issue-bot prestashop-issue-bot bot removed the Waiting for author Status: action required, waiting for author feedback label May 31, 2023
@JevgenijVisockij
Copy link
Contributor Author

Ready for review. Once this is merged #22471, #22139 and #20243 can be finished using the same logic that is updated here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
develop Branch Refactoring Type: Refactoring Wording ✔️ Status: check done, wording approved
Projects
Status: To be tested
Development

Successfully merging this pull request may close these issues.

None yet

10 participants