Skip to content

Commit

Permalink
Merge pull request #7318 from magento-honey-badgers/PWA-1611-nq-batch…
Browse files Browse the repository at this point in the history
…-operation-status

[honey] Negotiable Quote PWA-1611, PWA-1648
  • Loading branch information
pdohogne-magento authored Dec 21, 2021
2 parents 7996e89 + cc67611 commit 112c038
Show file tree
Hide file tree
Showing 32 changed files with 679 additions and 81 deletions.
8 changes: 6 additions & 2 deletions app/code/Magento/CatalogInventory/Model/StockManagement.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,12 @@
use Magento\CatalogInventory\Model\Spi\StockRegistryProviderInterface;
use Magento\Catalog\Api\ProductRepositoryInterface;
use Magento\CatalogInventory\Model\ResourceModel\Stock as ResourceStock;
use Magento\Framework\Exception\LocalizedException;

/**
* Implements a few interfaces for backward compatibility
*
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
*/
class StockManagement implements StockManagementInterface, RegisterProductSaleInterface, RevertProductSaleInterface
{
Expand Down Expand Up @@ -91,7 +94,8 @@ public function __construct(
* @param string[] $items
* @param int $websiteId
* @return StockItemInterface[]
* @throws \Magento\Framework\Exception\LocalizedException
* @throws StockStateException
* @throws LocalizedException
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
*/
public function registerProductsSale($items, $websiteId = null)
Expand All @@ -118,7 +122,7 @@ public function registerProductsSale($items, $websiteId = null)
&& !$this->stockState->checkQty($productId, $orderedQty, $stockItem->getWebsiteId())
) {
$this->getResource()->commit();
throw new \Magento\Framework\Exception\LocalizedException(
throw new StockStateException(
__('Some of the products are out of stock.')
);
}
Expand Down
17 changes: 17 additions & 0 deletions app/code/Magento/CatalogInventory/Model/StockStateException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
namespace Magento\CatalogInventory\Model;

use Magento\Framework\Exception\LocalizedException;

/**
* Exception class reflecting when an operation cannot be completed due to the current stock status of an inventory item
*
* @api
*/
class StockStateException extends LocalizedException
{
}
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ public function testRegisterProductsSale(
*/
public function testRegisterProductsSaleException(array $items, array $lockedItems)
{
$this->expectException('Magento\Framework\Exception\LocalizedException');
$this->expectException('Magento\CatalogInventory\Model\StockStateException');
$this->expectExceptionMessage('Some of the products are out of stock.');
$this->stockResourceMock
->expects($this->once())
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);

namespace Magento\CatalogInventoryGraphQl\Helper\Error\MessageFormatters;

use Magento\CatalogInventory\Model\StockStateException;
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\GraphQl\Config\Element\Field;
use Magento\Framework\GraphQl\Exception\GraphQlInputException;
use Magento\Framework\GraphQl\Query\Resolver\ContextInterface;
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
use Magento\GraphQl\Helper\Error\ExceptionMessageFormatterInterface;

/**
* Check if an internally-thrown exception is from an item stock status issue and re-throw with the message intact if so
*/
class StockStateExceptionMessageFormatter implements ExceptionMessageFormatterInterface
{
/**
* If the thrown exception was from an item stock status issue, allow the message to go through
*
* @param LocalizedException $e
* @param string $messagePrefix
* @param Field $field
* @param ContextInterface $context
* @param ResolveInfo $info
*
* @return GraphQlInputException|null
*/
public function getFormatted(
LocalizedException $e,
string $messagePrefix,
Field $field,
ContextInterface $context,
ResolveInfo $info
): ?GraphQlInputException {
if ($e instanceof StockStateException) {
return new GraphQlInputException(__("$messagePrefix: %message", ['message' => $e->getMessage()]), $e);
}
return null;
}
}
3 changes: 2 additions & 1 deletion app/code/Magento/CatalogInventoryGraphQl/composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
"magento/framework": "*",
"magento/module-store": "*",
"magento/module-catalog": "*",
"magento/module-catalog-inventory": "*"
"magento/module-catalog-inventory": "*",
"magento/module-graph-ql": "*"
},
"license": [
"OSL-3.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
use Magento\Catalog\Api\Data\ProductInterface;
use Magento\Catalog\Api\ProductRepositoryInterface;
use Magento\CatalogInventory\Api\StockStateInterface;
use Magento\CatalogInventory\Model\StockStateException;
use Magento\ConfigurableProductGraphQl\Model\Options\Collection as OptionCollection;
use Magento\Framework\EntityManager\MetadataPool;
use Magento\Framework\Exception\LocalizedException;
Expand Down Expand Up @@ -146,12 +147,13 @@ private function checkProductStock(string $sku, float $qty, int $scopeId): void
*
* @param string $parentSku
* @param array $superAttributesData
* @throws StockStateException
* @throws LocalizedException
*/
private function checkSuperAttributeData(string $parentSku, array $superAttributesData): void
{
if (empty($superAttributesData)) {
throw new LocalizedException(
throw new StockStateException(
__('The product with SKU %sku is out of stock.', ['sku' => $parentSku])
);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);

namespace Magento\GraphQl\Helper\Error;

use GraphQL\Error\ClientAware;
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\GraphQl\Config\Element\Field;
use Magento\Framework\GraphQl\Exception\GraphQlInputException;
use Magento\Framework\GraphQl\Query\Resolver\ContextInterface;
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
use Magento\Framework\Phrase;

/**
* Class for formatting internally-thrown errors if they match allowed exception types or using a default message if not
*/
class AggregateExceptionMessageFormatter
{
/**
* @var ExceptionMessageFormatterInterface[]
*/
private $messageFormatters;

/**
* @param ExceptionMessageFormatterInterface[] $messageFormatters
*/
public function __construct(array $messageFormatters)
{
$this->messageFormatters = $messageFormatters;
}

/**
* Format a thrown exception message if it matches one of the supplied formatters, otherwise use a default message
*
* @param LocalizedException $e
* @param Phrase $defaultMessage
* @param string $messagePrefix
* @param Field $field
* @param ContextInterface $context
* @param ResolveInfo $info
*
* @return ClientAware
*/
public function getFormatted(
LocalizedException $e,
Phrase $defaultMessage,
string $messagePrefix,
Field $field,
ContextInterface $context,
ResolveInfo $info
): ClientAware {
foreach ($this->messageFormatters as $formatter) {
$formatted = $formatter->getFormatted($e, $messagePrefix, $field, $context, $info);
if ($formatted) {
return $formatted;
}
}
return new GraphQlInputException($defaultMessage, $e);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);

namespace Magento\GraphQl\Helper\Error;

use GraphQL\Error\ClientAware;
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\GraphQl\Config\Element\Field;
use Magento\Framework\GraphQl\Query\Resolver\ContextInterface;
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;

/**
* Interface for formatting reportable internal error messages
*/
interface ExceptionMessageFormatterInterface
{
/**
* Re-throws a matching internal exception with the appropriate GraphQl exception type and user-safe message
*
* @param LocalizedException $e
* @param string $messagePrefix
* @param Field $field
* @param ContextInterface $context
* @param ResolveInfo $info
*
* @return ClientAware|null
*/
public function getFormatted(
LocalizedException $e,
string $messagePrefix,
Field $field,
ContextInterface $context,
ResolveInfo $info
): ?ClientAware;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);

namespace Magento\GraphQl\Helper\Error\MessageFormatters;

use GraphQL\Error\ClientAware;
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\GraphQl\Config\Element\Field;
use Magento\Framework\GraphQl\Exception\GraphQlAlreadyExistsException;
use Magento\Framework\GraphQl\Exception\GraphQlAuthenticationException;
use Magento\Framework\GraphQl\Exception\GraphQlAuthorizationException;
use Magento\Framework\GraphQl\Exception\GraphQlInputException;
use Magento\Framework\GraphQl\Exception\GraphQlNoSuchEntityException;
use Magento\Framework\GraphQl\Query\Resolver\ContextInterface;
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
use Magento\GraphQl\Helper\Error\ExceptionMessageFormatterInterface;

/**
* Check if a thrown exception is already formatted for GraphQL and re-throw with no changes if so
*/
class GraphQlExceptionMessageFormatter implements ExceptionMessageFormatterInterface
{
/**
* If the thrown exception is already formatted for GraphQl, re-throw it with no changes
*
* @param LocalizedException $e
* @param string $messagePrefix
* @param Field $field
* @param ContextInterface $context
* @param ResolveInfo $info
*
* @return GraphQlAlreadyExistsException|GraphQlAuthenticationException|GraphQlAuthorizationException|GraphQlInputException|GraphQlNoSuchEntityException|null
*/
public function getFormatted(
LocalizedException $e,
string $messagePrefix,
Field $field,
ContextInterface $context,
ResolveInfo $info
): ?ClientAware {
if ($e instanceof GraphQlAlreadyExistsException
|| $e instanceof GraphQlAuthenticationException
|| $e instanceof GraphQlAuthorizationException
|| $e instanceof GraphQlInputException
|| $e instanceof GraphQlNoSuchEntityException) {
return $e;
}
return null;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);

namespace Magento\GraphQl\Helper\Error\MessageFormatters;

use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\Exception\NoSuchEntityException;
use Magento\Framework\GraphQl\Config\Element\Field;
use Magento\Framework\GraphQl\Exception\GraphQlNoSuchEntityException;
use Magento\Framework\GraphQl\Query\Resolver\ContextInterface;
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
use Magento\GraphQl\Helper\Error\ExceptionMessageFormatterInterface;

/**
* Check if an internally-thrown exception is a NoSuchEntityException and re-throw with the message intact if so
*/
class NoSuchEntityExceptionMessageFormatter implements ExceptionMessageFormatterInterface
{
/**
* If the thrown exception was a NoSuchEntityException, allow the message to go through
*
* @param LocalizedException $e
* @param string $messagePrefix
* @param Field $field
* @param ContextInterface $context
* @param ResolveInfo $info
*
* @return GraphQlNoSuchEntityException|null
*/
public function getFormatted(
LocalizedException $e,
string $messagePrefix,
Field $field,
ContextInterface $context,
ResolveInfo $info
): ?GraphQlNoSuchEntityException {
if ($e instanceof NoSuchEntityException) {
return new GraphQlNoSuchEntityException(__($e->getMessage()), $e);
}
return null;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);

namespace Magento\GraphQl\Helper\Error\MessageFormatters;

use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\Exception\PaymentException;
use Magento\Framework\GraphQl\Config\Element\Field;
use Magento\Framework\GraphQl\Exception\GraphQlInputException;
use Magento\Framework\GraphQl\Query\Resolver\ContextInterface;
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
use Magento\GraphQl\Helper\Error\ExceptionMessageFormatterInterface;

/**
* Check if an internally-thrown exception is from a payment issue and re-throw with the message intact if so
*/
class PaymentExceptionMessageFormatter implements ExceptionMessageFormatterInterface
{
/**
* If the thrown exception was from a payment issue, allow the message to go through
*
* @param LocalizedException $e
* @param string $messagePrefix
* @param Field $field
* @param ContextInterface $context
* @param ResolveInfo $info
*
* @return GraphQlInputException|null
*/
public function getFormatted(
LocalizedException $e,
string $messagePrefix,
Field $field,
ContextInterface $context,
ResolveInfo $info
): ?GraphQlInputException {
if ($e instanceof PaymentException) {
return new GraphQlInputException(__("$messagePrefix: %message", ['message' => $e->getMessage()]), $e);
}
return null;
}
}
Loading

0 comments on commit 112c038

Please sign in to comment.