From 04f60d5d27f661b2a33c1f6db2ef511ab5ff3c2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20F=C3=BChr?= Date: Fri, 8 Mar 2019 23:20:21 +0100 Subject: [PATCH 1/3] 18752: make root cause visible for exception on submitQuote Github Issue: https://github.com/magento/magento2/issues/18752 If an exceptions happens in orderManagement->place($order) or an "sales_model_service_quote_submit_success" observer, the catch block itself fires an event that currently fails for guest checkouts in Magento\CatalogInventory\Model\ResourceModel\Stock->correctItemsQty(). This second exception hides the root exception and is logged to the exception log with the message "Rolled back transaction has not been completed correctly". This is not bound for this observer, but may occur in every other observer that is currently register or may be registered in the future. Therefore the failure event is wrapped in a try-catch itself and throws a combined exception that is logged in the exception.log. --- .../Magento/Quote/Model/QuoteManagement.php | 35 +++++++++++++------ 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/app/code/Magento/Quote/Model/QuoteManagement.php b/app/code/Magento/Quote/Model/QuoteManagement.php index 8f216b64aa9b0..b10777f816fdf 100644 --- a/app/code/Magento/Quote/Model/QuoteManagement.php +++ b/app/code/Magento/Quote/Model/QuoteManagement.php @@ -12,6 +12,7 @@ use Magento\Framework\Exception\CouldNotSaveException; use Magento\Framework\Exception\LocalizedException; use Magento\Framework\Exception\StateException; +use Magento\Framework\Phrase; use Magento\Quote\Api\Data\PaymentInterface; use Magento\Quote\Model\Quote\Address\ToOrder as ToOrderConverter; use Magento\Quote\Model\Quote\Address\ToOrderAddress as ToOrderAddressConverter; @@ -532,19 +533,31 @@ protected function submitQuote(QuoteEntity $quote, $orderData = []) ); $this->quoteRepository->save($quote); } catch (\Exception $e) { - if (!empty($this->addressesToSync)) { - foreach ($this->addressesToSync as $addressId) { - $this->addressRepository->deleteById($addressId); + try { + if (!empty($this->addressesToSync)) { + foreach ($this->addressesToSync as $addressId) { + $this->addressRepository->deleteById($addressId); + } } + $this->eventManager->dispatch( + 'sales_model_service_quote_submit_failure', + [ + 'order' => $order, + 'quote' => $quote, + 'exception' => $e, + ] + ); + } catch (\Exception $consecutiveException) { + $message = new Phrase( + "An exception occurred on 'sales_model_service_quote_submit_failure' event: %1\n%2", + [ + $consecutiveException->getMessage(), + $consecutiveException->getTraceAsString() + ] + ); + + throw new LocalizedException($message, $e); } - $this->eventManager->dispatch( - 'sales_model_service_quote_submit_failure', - [ - 'order' => $order, - 'quote' => $quote, - 'exception' => $e - ] - ); throw $e; } return $order; From 6b0ebf49055d0ee4bb371ffc23186eef2eb02fb7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20F=C3=BChr?= Date: Mon, 11 Mar 2019 15:48:37 +0100 Subject: [PATCH 2/3] amend consecutive exception handling - support masking of root cause in frontend - remove stack trace for consecutive exception to comply to default behaviour --- app/code/Magento/Quote/Model/QuoteManagement.php | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/app/code/Magento/Quote/Model/QuoteManagement.php b/app/code/Magento/Quote/Model/QuoteManagement.php index b10777f816fdf..e1058c98271c1 100644 --- a/app/code/Magento/Quote/Model/QuoteManagement.php +++ b/app/code/Magento/Quote/Model/QuoteManagement.php @@ -12,7 +12,6 @@ use Magento\Framework\Exception\CouldNotSaveException; use Magento\Framework\Exception\LocalizedException; use Magento\Framework\Exception\StateException; -use Magento\Framework\Phrase; use Magento\Quote\Api\Data\PaymentInterface; use Magento\Quote\Model\Quote\Address\ToOrder as ToOrderConverter; use Magento\Quote\Model\Quote\Address\ToOrderAddress as ToOrderAddressConverter; @@ -548,15 +547,12 @@ protected function submitQuote(QuoteEntity $quote, $orderData = []) ] ); } catch (\Exception $consecutiveException) { - $message = new Phrase( - "An exception occurred on 'sales_model_service_quote_submit_failure' event: %1\n%2", - [ - $consecutiveException->getMessage(), - $consecutiveException->getTraceAsString() - ] + $message = sprintf( + "An exception occurred on 'sales_model_service_quote_submit_failure' event: %s", + $consecutiveException->getMessage() ); - throw new LocalizedException($message, $e); + throw new \Exception($message, 0, $e); } throw $e; } From 59771c40c1a2aa857d3b64b0905aa67c1705a1c9 Mon Sep 17 00:00:00 2001 From: nmalevanec Date: Mon, 25 Mar 2019 14:58:00 +0200 Subject: [PATCH 3/3] Fix static tests. --- .../Magento/Quote/Model/QuoteManagement.php | 60 ++++++++++++------- 1 file changed, 38 insertions(+), 22 deletions(-) diff --git a/app/code/Magento/Quote/Model/QuoteManagement.php b/app/code/Magento/Quote/Model/QuoteManagement.php index e1058c98271c1..2fcfd2dfadabb 100644 --- a/app/code/Magento/Quote/Model/QuoteManagement.php +++ b/app/code/Magento/Quote/Model/QuoteManagement.php @@ -532,28 +532,7 @@ protected function submitQuote(QuoteEntity $quote, $orderData = []) ); $this->quoteRepository->save($quote); } catch (\Exception $e) { - try { - if (!empty($this->addressesToSync)) { - foreach ($this->addressesToSync as $addressId) { - $this->addressRepository->deleteById($addressId); - } - } - $this->eventManager->dispatch( - 'sales_model_service_quote_submit_failure', - [ - 'order' => $order, - 'quote' => $quote, - 'exception' => $e, - ] - ); - } catch (\Exception $consecutiveException) { - $message = sprintf( - "An exception occurred on 'sales_model_service_quote_submit_failure' event: %s", - $consecutiveException->getMessage() - ); - - throw new \Exception($message, 0, $e); - } + $this->rollbackAddresses($quote, $order, $e); throw $e; } return $order; @@ -620,4 +599,41 @@ protected function _prepareCustomerQuote($quote) $shipping->setIsDefaultBilling(true); } } + + /** + * Remove related to order and quote addresses and submit exception to further processing. + * + * @param Quote $quote + * @param \Magento\Sales\Api\Data\OrderInterface $order + * @param \Exception $e + * @throws \Exception + */ + private function rollbackAddresses( + QuoteEntity $quote, + \Magento\Sales\Api\Data\OrderInterface $order, + \Exception $e + ): void { + try { + if (!empty($this->addressesToSync)) { + foreach ($this->addressesToSync as $addressId) { + $this->addressRepository->deleteById($addressId); + } + } + $this->eventManager->dispatch( + 'sales_model_service_quote_submit_failure', + [ + 'order' => $order, + 'quote' => $quote, + 'exception' => $e, + ] + ); + } catch (\Exception $consecutiveException) { + $message = sprintf( + "An exception occurred on 'sales_model_service_quote_submit_failure' event: %s", + $consecutiveException->getMessage() + ); + + throw new \Exception($message, 0, $e); + } + } }