Skip to content

False positive - Direct throw of generic Exception is discouraged #194

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

Closed
ihor-sviziev opened this issue Aug 20, 2020 · 4 comments
Closed
Assignees
Labels
bug Something isn't working Progress: done

Comments

@ihor-sviziev
Copy link
Collaborator

Preconditions

  1. Magento 2.4-develop
  2. Latest coding standards

Steps to reproduce

  1. Create file with following content:
<?php
/**
 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */
declare(strict_types=1);

namespace Magento\LoginAsCustomerAssistance\Plugin;

use Magento\Customer\Model\Metadata\Form;
use Magento\Framework\App\RequestInterface;
use Magento\Framework\AuthorizationInterface;
use Magento\Framework\Message\MessageInterface;
use Magento\Framework\Validator\Exception;
use Magento\LoginAsCustomerAssistance\Api\IsAssistanceEnabledInterface;
use Magento\LoginAsCustomerAssistance\Model\ResourceModel\GetLoginAsCustomerAssistanceAllowed;

/**
 * Check if User have permission to change Customers Opt-In preference.
 */
class CustomerDataValidatePlugin
{
    /**
     * @var AuthorizationInterface
     */
    private $authorization;

    /**
     * @var GetLoginAsCustomerAssistanceAllowed
     */
    private $getLoginAsCustomerAssistanceAllowed;

    /**
     * @param AuthorizationInterface $authorization
     * @param GetLoginAsCustomerAssistanceAllowed $getLoginAsCustomerAssistanceAllowed
     */
    public function __construct(
        AuthorizationInterface $authorization,
        GetLoginAsCustomerAssistanceAllowed $getLoginAsCustomerAssistanceAllowed
    ) {
        $this->authorization = $authorization;
        $this->getLoginAsCustomerAssistanceAllowed = $getLoginAsCustomerAssistanceAllowed;
    }

    /**
     * Check if User have permission to change Customers Opt-In preference.
     *
     * @param Form $subject
     * @param RequestInterface $request
     * @param null|string $scope
     * @param bool $scopeOnly
     * @throws Exception
     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
     */
    public function beforeExtractData(
        Form $subject,
        RequestInterface $request,
        $scope = null,
        $scopeOnly = true
    ): void {
        if ($this->isSetAssistanceAllowedParam($request)
            && !$this->authorization->isAllowed('Magento_LoginAsCustomer::allow_shopping_assistance')
        ) {
            $customerId = $request->getParam('customer_id');
            $assistanceAllowedParam =
                (int)$request->getParam('customer')['extension_attributes']['assistance_allowed'];
            $assistanceAllowed = $this->getLoginAsCustomerAssistanceAllowed->execute((int)$customerId);
            $assistanceAllowedStatus = $this->resolveStatus($assistanceAllowed);
            if ($this->isAssistanceAllowedChangeImportant($assistanceAllowedStatus, $assistanceAllowedParam)) {
                $errorMessages = [
                    MessageInterface::TYPE_ERROR => [
                        __(
                            'You have no permission to change Opt-In preference.'
                        ),
                    ],
                ];

                throw new Exception(null, null, $errorMessages);
            }
        }
    }

    /**
     * Check if assistance_allowed param is set.
     *
     * @param RequestInterface $request
     * @return bool
     */
    private function isSetAssistanceAllowedParam(RequestInterface $request): bool
    {
        return is_array($request->getParam('customer'))
            && isset($request->getParam('customer')['extension_attributes'])
            && isset($request->getParam('customer')['extension_attributes']['assistance_allowed']);
    }

    /**
     * Check if change of assistance_allowed attribute is important.
     *
     * E. g. if assistance_allowed is going to be disabled while now it's enabled
     * or if it's going to be enabled while now it is disabled or not set at all.
     *
     * @param int $assistanceAllowed
     * @param int $assistanceAllowedParam
     * @return bool
     */
    private function isAssistanceAllowedChangeImportant(int $assistanceAllowed, int $assistanceAllowedParam): bool
    {
        $result = false;
        if (($assistanceAllowedParam === IsAssistanceEnabledInterface::DENIED
                && $assistanceAllowed === IsAssistanceEnabledInterface::ALLOWED)
            ||
            ($assistanceAllowedParam === IsAssistanceEnabledInterface::ALLOWED
                && $assistanceAllowed !== IsAssistanceEnabledInterface::ALLOWED)) {
            $result = true;
        }

        return $result;
    }

    /**
     * Get integer status value from boolean.
     *
     * @param bool $assistanceAllowed
     * @return int
     */
    private function resolveStatus(bool $assistanceAllowed): int
    {
        return $assistanceAllowed ? IsAssistanceEnabledInterface::ALLOWED : IsAssistanceEnabledInterface::DENIED;
    }
}
  1. Run coding standards against it

Expected result

  1. You shouldn't have any issues with it, especially message "Direct throw of generic Exception is discouraged. Use context specific instead" should not appear as "Exception" class is imported from Magento\Framework\Validator\Exception at the top of the file.

Actual result

PHP Code Sniffer detected 1 violation(s): 

FILE: .../LoginAsCustomerAssistance/Plugin/CustomerDataValidatePlugin.php
----------------------------------------------------------------------
FOUND 0 ERRORS AND 1 WARNING AFFECTING 1 LINE
----------------------------------------------------------------------
 74 | WARNING | Direct throw of generic Exception is discouraged. Use
    |         | context specific instead.
----------------------------------------------------------------------

Additional info

We found this issue on the following PR: magento/magento2#29688

@ihor-sviziev ihor-sviziev added the bug Something isn't working label Aug 20, 2020
@m2-assistant
Copy link

m2-assistant bot commented Aug 20, 2020

Hi @ihor-sviziev. Thank you for your report.
To help us process this issue please make sure that you provided sufficient information.

Please, add a comment to assign the issue: @magento I am working on this


@ivancukns
Copy link

Until this gets fixed by Magento, one possible workaround is to assign an alias to this Exception class, like this:
use Magento\Framework\Validator\Exception as ValidatorException;

Same goes for all classes that are named like the base generic Exception class.

@rmsundar1
Copy link
Contributor

@magento I am working on this

@ihor-sviziev
Copy link
Collaborator Author

Hi @svera,
Could you please explain why did you close the issue and PR and didn't leave any comment?

magento-devops-reposync-svc pushed a commit that referenced this issue Oct 17, 2022
AC-6437:Ensure PHP8.1 support after 7.4 removal - Added support for R…
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working Progress: done
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants