diff --git a/CHANGELOG.md b/CHANGELOG.md index 3aacb1b55..62638004c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ -# 16.0.1 +# 16.1.0 +- Fixed log entries to have the file path and line number in the exception message +- Remove support for Magento 1.9 - Reduced log file size by removing exception trace args # 16.0.0 diff --git a/CHANGELOG_de-DE.md b/CHANGELOG_de-DE.md index 04f62fe33..4baf5c162 100644 --- a/CHANGELOG_de-DE.md +++ b/CHANGELOG_de-DE.md @@ -1,5 +1,7 @@ -# 16.0.1 +# 16.1.0 +- Log-Einträge wurden korrigiert, sodass der Dateipfad und die Zeilennummer nun in der Ausnahmemeldung enthalten sind. +- Die Unterstützung für Magento 1.9 wurde entfernt. - Größe der Protokolldatei reduziert, indem Exception-Trace Argumente entfernt wurden # 16.0.0 diff --git a/composer.json b/composer.json index 15c948d1e..ae815ffc5 100644 --- a/composer.json +++ b/composer.json @@ -1,7 +1,7 @@ { "name": "swag/migration-assistant", "description": "Migration plugin for shopware/platform", - "version": "16.0.0", + "version": "16.1.0", "type": "shopware-platform-plugin", "license": "MIT", "authors": [ diff --git a/src/Exception/MigrationException.php b/src/Exception/MigrationException.php index c477e289b..755ab62cb 100644 --- a/src/Exception/MigrationException.php +++ b/src/Exception/MigrationException.php @@ -105,6 +105,8 @@ class MigrationException extends HttpException public const LOCAL_DATABASE_CONNECTION_ERROR = 'SWAG_MIGRATION__LOCAL_DATABASE_CONNECTION_ERROR'; + final public const MAIN_VARIANT_RELATION_MISSING_ID_AND_ORDER_NUMBER = 'SWAG_MIGRATION__MAIN_VARIANT_RELATION_MISSING_ID_AND_ORDER_NUMBER'; + public static function associationEntityRequiredMissing(string $entity, string $missingEntity): self { return new self( @@ -556,4 +558,13 @@ public static function connectionValidationFailed(string $code, string $message) $message, ); } + + public static function mainVariantRelationMissingIdAndOrderNumber(): self + { + return new self( + Response::HTTP_INTERNAL_SERVER_ERROR, + self::MAIN_VARIANT_RELATION_MISSING_ID_AND_ORDER_NUMBER, + 'MainVariantRelation requires ID and order number.', + ); + } } diff --git a/src/Migration/Converter/ConverterRegistry.php b/src/Migration/Converter/ConverterRegistry.php index 77fbe39a3..0ce03f502 100644 --- a/src/Migration/Converter/ConverterRegistry.php +++ b/src/Migration/Converter/ConverterRegistry.php @@ -32,6 +32,11 @@ public function getConverter(MigrationContextInterface $migrationContext): Conve } } - throw MigrationException::converterNotFound($migrationContext->getProfile()->getName()); + $dataSet = $migrationContext->getDataSet(); + if ($dataSet === null) { + throw MigrationException::migrationContextPropertyMissing('DataSet'); + } + + throw MigrationException::converterNotFound($dataSet::getEntity()); } } diff --git a/src/Migration/Logging/Log/Builder/MigrationLogBuilder.php b/src/Migration/Logging/Log/Builder/MigrationLogBuilder.php index eaf1cf556..9bf8f6e2a 100644 --- a/src/Migration/Logging/Log/Builder/MigrationLogBuilder.php +++ b/src/Migration/Logging/Log/Builder/MigrationLogBuilder.php @@ -40,6 +40,7 @@ public function __construct( protected ?array $convertedData = null, protected ?string $exceptionMessage = null, protected ?array $exceptionTrace = null, + protected ?\Throwable $exception = null, ) { } @@ -100,6 +101,13 @@ public function withConvertedData(array $convertedData): self return $this; } + public function withException(\Throwable $exception): self + { + $this->exception = $exception; + + return $this; + } + public function withExceptionMessage(string $exceptionMessage): self { $this->exceptionMessage = $exceptionMessage; @@ -128,13 +136,6 @@ public function build(string $logClass): AbstractMigrationLogEntry { \assert(\class_exists($logClass) && \is_subclass_of($logClass, AbstractMigrationLogEntry::class)); - if ($this->exceptionTrace !== null) { - // remove args from trace, as they quickly become too large - foreach ($this->exceptionTrace as &$trace) { - unset($trace['args']); - } - } - return new $logClass( $this->runId, $this->profileName, @@ -145,8 +146,8 @@ public function build(string $logClass): AbstractMigrationLogEntry $this->fieldSourcePath, $this->sourceData, $this->convertedData, - $this->exceptionMessage, - $this->exceptionTrace, + $this->getExceptionMessage(), + $this->getExceptionTrace(), ); } @@ -162,4 +163,33 @@ private function getRevisedId(?string $id): ?string return null; } + + private function getExceptionMessage(): ?string + { + if ($this->exceptionMessage !== null) { + return $this->exceptionMessage; + } + + if ($this->exception !== null) { + return $this->exception->getMessage() . ' in ' . $this->exception->getFile() . ':' . $this->exception->getLine(); + } + + return null; + } + + /** + * @return array|null + */ + private function getExceptionTrace(): ?array + { + $trace = $this->exceptionTrace ?? $this->exception?->getTrace(); + + if ($trace !== null) { + foreach ($trace as &$traceEntry) { + unset($traceEntry['args']); + } + } + + return $trace; + } } diff --git a/src/Migration/Media/Processor/HttpDownloadServiceBase.php b/src/Migration/Media/Processor/HttpDownloadServiceBase.php index 179861642..2e6ea39cc 100644 --- a/src/Migration/Media/Processor/HttpDownloadServiceBase.php +++ b/src/Migration/Media/Processor/HttpDownloadServiceBase.php @@ -80,8 +80,7 @@ public function process(MigrationContextInterface $migrationContext, Context $co $this->loggingService->log( MigrationLogBuilder::fromMigrationContext($migrationContext) - ->withExceptionMessage($exception->getMessage()) - ->withExceptionTrace($exception->getTrace()) + ->withException($exception) ->withEntityName(MediaDefinition::ENTITY_NAME) ->build(RunExceptionLog::class) ); @@ -188,8 +187,7 @@ function (MediaProcessWorkloadStruct $work) use ($uuid) { $work->setState(MediaProcessWorkloadStruct::ERROR_STATE); $this->loggingService->log( MigrationLogBuilder::fromMigrationContext($migrationContext) - ->withExceptionMessage($e->getMessage()) - ->withExceptionTrace($e->getTrace()) + ->withException($e) ->withEntityName(MediaDefinition::ENTITY_NAME) ->withEntityId($uuid) ->build(RunExceptionLog::class) @@ -287,8 +285,7 @@ private function doNormalDownloadRequest(MigrationContextInterface $migrationCon // this should never happen because of Promises, but just in case something is wrong with request construction $this->loggingService->log( MigrationLogBuilder::fromMigrationContext($migrationContext) - ->withExceptionMessage($exception->getMessage()) - ->withExceptionTrace($exception->getTrace()) + ->withException($exception) ->withEntityName(MediaDefinition::ENTITY_NAME) ->build(RunExceptionLog::class) ); @@ -311,8 +308,7 @@ private function persistFileToMedia(string $filePath, string $uuid, string $name $this->loggingService->log( MigrationLogBuilder::fromMigrationContext($migrationContext) - ->withExceptionMessage($exception->getMessage()) - ->withExceptionTrace($exception->getTrace()) + ->withException($exception) ->withEntityName(MediaDefinition::ENTITY_NAME) ->build(RunExceptionLog::class) ); @@ -347,8 +343,7 @@ private function persistFileToMedia(string $filePath, string $uuid, string $name } else { $this->loggingService->log( MigrationLogBuilder::fromMigrationContext($migrationContext) - ->withExceptionMessage($mediaException->getMessage()) - ->withExceptionTrace($mediaException->getTrace()) + ->withException($mediaException) ->withEntityName(MediaDefinition::ENTITY_NAME) ->build(RunExceptionLog::class) ); diff --git a/src/Migration/MessageQueue/Handler/Processor/MediaProcessingProcessor.php b/src/Migration/MessageQueue/Handler/Processor/MediaProcessingProcessor.php index fc6bc2587..16ce56703 100644 --- a/src/Migration/MessageQueue/Handler/Processor/MediaProcessingProcessor.php +++ b/src/Migration/MessageQueue/Handler/Processor/MediaProcessingProcessor.php @@ -140,8 +140,7 @@ public function process( if ($e->getErrorCode() === MigrationException::NO_CONNECTION_FOUND) { $this->loggingService->log( MigrationLogBuilder::fromMigrationContext($migrationContext) - ->withExceptionMessage($e->getMessage()) - ->withExceptionTrace($e->getTrace()) + ->withException($e) ->withEntityName($currentDataSet::getEntity()) ->build(FetchProcessorMissingLog::class) ); @@ -151,8 +150,7 @@ public function process( } catch (\Throwable $e) { $this->loggingService->log( MigrationLogBuilder::fromMigrationContext($migrationContext) - ->withExceptionMessage($e->getMessage()) - ->withExceptionTrace($e->getTrace()) + ->withException($e) ->withEntityName($currentDataSet::getEntity()) ->build(RunExceptionLog::class) ); diff --git a/src/Migration/Run/RunService.php b/src/Migration/Run/RunService.php index e7711dfa2..22847dfb9 100644 --- a/src/Migration/Run/RunService.php +++ b/src/Migration/Run/RunService.php @@ -287,8 +287,7 @@ public function assignThemeToSalesChannel(string $runUuid, Context $context): vo $connection->getProfileName(), $connection->getGatewayName(), )) - ->withExceptionMessage($exception->getMessage()) - ->withExceptionTrace($exception->getTrace()) + ->withException($exception) ->withEntityName(ThemeDefinition::ENTITY_NAME) ->withEntityId($defaultThemeId) ->build(WriteThemeCompilingFailedLog::class) diff --git a/src/Migration/Service/MigrationDataConverter.php b/src/Migration/Service/MigrationDataConverter.php index 92a56366e..1985f7223 100644 --- a/src/Migration/Service/MigrationDataConverter.php +++ b/src/Migration/Service/MigrationDataConverter.php @@ -74,8 +74,7 @@ public function convert(array $data, MigrationContextInterface $migrationContext } catch (\Throwable $exception) { $this->loggingService->log( MigrationLogBuilder::fromMigrationContext($migrationContext) - ->withExceptionMessage($exception->getMessage()) - ->withExceptionTrace($exception->getTrace()) + ->withException($exception) ->withEntityName($dataSet::getEntity()) ->build(RunExceptionLog::class) ); @@ -128,8 +127,7 @@ private function convertData( } catch (\Throwable $exception) { $this->loggingService->log( MigrationLogBuilder::fromMigrationContext($migrationContext) - ->withExceptionMessage($exception->getMessage()) - ->withExceptionTrace($exception->getTrace()) + ->withException($exception) ->withEntityName($dataSet::getEntity()) ->withSourceData($item) ->build(RunExceptionLog::class) diff --git a/src/Migration/Service/MigrationDataFetcher.php b/src/Migration/Service/MigrationDataFetcher.php index fbc1e2679..08b20ee57 100644 --- a/src/Migration/Service/MigrationDataFetcher.php +++ b/src/Migration/Service/MigrationDataFetcher.php @@ -37,8 +37,7 @@ public function fetchData(MigrationContextInterface $migrationContext, Context $ } catch (\Throwable $exception) { $this->loggingService->log( MigrationLogBuilder::fromMigrationContext($migrationContext) - ->withExceptionMessage($exception->getMessage()) - ->withExceptionTrace($exception->getTrace()) + ->withException($exception) ->withEntityName($dataSet::getEntity()) ->build(RunExceptionLog::class) ); diff --git a/src/Migration/Service/MigrationDataWriter.php b/src/Migration/Service/MigrationDataWriter.php index a00f76444..5366c0c85 100644 --- a/src/Migration/Service/MigrationDataWriter.php +++ b/src/Migration/Service/MigrationDataWriter.php @@ -119,8 +119,7 @@ public function writeData(MigrationContextInterface $migrationContext, Context $ } catch (MigrationException $writerNotFoundException) { $this->loggingService->log( MigrationLogBuilder::fromMigrationContext($migrationContext) - ->withExceptionMessage($writerNotFoundException->getMessage()) - ->withExceptionTrace($writerNotFoundException->getTrace()) + ->withException($writerNotFoundException) ->withConvertedData([$converted]) ->withEntityName($dataSet::getEntity()) ->build(RunExceptionLog::class) @@ -202,8 +201,7 @@ private function handleWriteException( $this->loggingService->log( MigrationLogBuilder::fromMigrationContext($migrationContext) - ->withExceptionMessage($exception->getMessage()) - ->withExceptionTrace($exception->getTrace()) + ->withException($exception) ->withEntityName($entityName) ->withConvertedData($entity) ->withEntityId($entity['id'] ?? null) @@ -261,12 +259,11 @@ private function writePerEntity( } catch (\Throwable $exception) { $this->loggingService->log( MigrationLogBuilder::fromMigrationContext($migrationContext) - ->withExceptionMessage($exception->getMessage()) - ->withExceptionTrace($exception->getTrace()) + ->withException($exception) ->withEntityName($entityName) ->withConvertedData([$entity]) ->withEntityId($entity['id'] ?? null) - ->build(RunExceptionLog::class) + ->build(WriteExceptionLog::class) ); $updateWrittenData[$dataId]['written'] = false; diff --git a/src/Migration/Subscriber/MessageQueueSubscriber.php b/src/Migration/Subscriber/MessageQueueSubscriber.php index 492bf0bab..3e801f0a9 100644 --- a/src/Migration/Subscriber/MessageQueueSubscriber.php +++ b/src/Migration/Subscriber/MessageQueueSubscriber.php @@ -95,8 +95,7 @@ public function onWorkerMessageFailed(WorkerMessageFailedEvent $event): void $connection?->getProfileName() ?? 'unknown', $connection?->getGatewayName() ?? 'unknown' )) - ->withExceptionMessage($event->getThrowable()->getMessage()) - ->withExceptionTrace($event->getThrowable()->getTrace()) + ->withException($event->getThrowable()) ->build(RunMessageQueueExceptionLog::class) ); @@ -114,8 +113,7 @@ public function onWorkerMessageFailed(WorkerMessageFailedEvent $event): void $connection?->getProfileName() ?? 'unknown', $connection?->getGatewayName() ?? 'unknown' )) - ->withExceptionMessage($event->getThrowable()->getMessage()) - ->withExceptionTrace($event->getThrowable()->getTrace()) + ->withException($event->getThrowable()) ->build(RunAbortedLog::class) ); diff --git a/src/Migration/Validation/MigrationEntityValidationService.php b/src/Migration/Validation/MigrationEntityValidationService.php index 0bf50b7cc..a33d6b42d 100644 --- a/src/Migration/Validation/MigrationEntityValidationService.php +++ b/src/Migration/Validation/MigrationEntityValidationService.php @@ -528,8 +528,7 @@ private function addValidationExceptionLog( ->withFieldName($fieldName) ->withConvertedData($validationContext->getConvertedData()) ->withSourceData($validationContext->getSourceData()) - ->withExceptionMessage($exception->getMessage()) - ->withExceptionTrace($exception->getTrace()) + ->withException($exception) ->withEntityId($entityId) ->build($logClass) ); @@ -545,8 +544,7 @@ private function addExceptionLog(MigrationValidationContext $validationContext, ->withEntityName($validationContext->getEntityDefinition()->getEntityName()) ->withSourceData($validationContext->getSourceData()) ->withConvertedData($convertedData) - ->withExceptionMessage($exception->getMessage()) - ->withExceptionTrace($exception->getTrace()) + ->withException($exception) ->withEntityId($entityId) ->build(MigrationValidationExceptionLog::class) ); diff --git a/src/Migration/Writer/OrderWriter.php b/src/Migration/Writer/OrderWriter.php index 3062b6b26..338cf9870 100644 --- a/src/Migration/Writer/OrderWriter.php +++ b/src/Migration/Writer/OrderWriter.php @@ -33,6 +33,10 @@ public function supports(): string public function writeData(array $data, Context $context): array { foreach ($data as &$item) { + if (!isset($item['transactions']) || !\is_array($item['transactions'])) { + continue; + } + foreach ($item['transactions'] as &$transaction) { $transaction['amount'] = $this->structNormalizer->denormalize($transaction['amount']); } diff --git a/src/Profile/Shopware/Converter/MainVariantRelationConverter.php b/src/Profile/Shopware/Converter/MainVariantRelationConverter.php index 76e822e68..fb0a71e3f 100644 --- a/src/Profile/Shopware/Converter/MainVariantRelationConverter.php +++ b/src/Profile/Shopware/Converter/MainVariantRelationConverter.php @@ -9,6 +9,7 @@ use Shopware\Core\Framework\Context; use Shopware\Core\Framework\Log\Package; +use SwagMigrationAssistant\Exception\MigrationException; use SwagMigrationAssistant\Migration\Converter\ConvertStruct; use SwagMigrationAssistant\Migration\DataSelection\DefaultEntities; use SwagMigrationAssistant\Migration\Logging\Log\Builder\MigrationLogBuilder; @@ -35,11 +36,12 @@ public function convert(array $data, Context $context, MigrationContextInterface $this->connectionId = $connection->getId(); if (!isset($data['id'], $data['ordernumber'])) { + $exception = MigrationException::mainVariantRelationMissingIdAndOrderNumber(); + $this->loggingService->log( MigrationLogBuilder::fromMigrationContext($migrationContext) ->withSourceData($data) - ->withExceptionMessage('MainVariantRelation requires ID and order number, to be converted successful') - ->withExceptionTrace(\debug_backtrace(\DEBUG_BACKTRACE_IGNORE_ARGS, 2)) + ->withException($exception) ->build(ConvertMainVariantRelationFailedLog::class) ); diff --git a/src/Profile/Shopware/Converter/ProductConverter.php b/src/Profile/Shopware/Converter/ProductConverter.php index e9d534751..55c0c2b02 100644 --- a/src/Profile/Shopware/Converter/ProductConverter.php +++ b/src/Profile/Shopware/Converter/ProductConverter.php @@ -916,8 +916,7 @@ private function getEsdFiles(array $esdFiles, string $oldVariantId, array $conve ->withFieldName('path') ->withFieldSourcePath('path') ->withSourceData($esdFile) - ->withExceptionMessage($e->getMessage()) - ->withExceptionTrace($e->getTrace()) + ->withException($e) ->build(ConvertChildEntityFailedLog::class) ); diff --git a/src/Profile/Shopware/Converter/TranslationConverter.php b/src/Profile/Shopware/Converter/TranslationConverter.php index 06a49a582..7eb4c0c3c 100644 --- a/src/Profile/Shopware/Converter/TranslationConverter.php +++ b/src/Profile/Shopware/Converter/TranslationConverter.php @@ -961,31 +961,30 @@ protected function addAttribute(string $entityName, string $key, string $value, protected function unserializeTranslation(array $data, string $entity): ?array { $objectDataSerialized = $data['objectdata']; - $exception = null; try { /** @phpstan-ignore shopware.unserializeUsage */ $objectData = \unserialize($objectDataSerialized, ['allowed_classes' => false]); - } catch (\Throwable $e) { - $objectData = null; - $exception = $e; - } - if (!\is_array($objectData)) { - $this->loggingService->log( - MigrationLogBuilder::fromMigrationContext($this->migrationContext) - ->withEntityName($entity) - ->withFieldSourcePath('objectdata') - ->withSourceData($data) - ->withExceptionMessage($exception?->getMessage() ?? 'Unserialization failed') - ->withExceptionTrace($exception?->getTrace() ?? []) - ->build(ConvertUnserializedDataInvalidLog::class) - ); + if (\is_array($objectData)) { + return $objectData; + } - return null; + $error = new \UnexpectedValueException('Unserialized data is not an array'); + } catch (\Throwable $e) { + $error = $e; } - return $objectData; + $this->loggingService->log( + MigrationLogBuilder::fromMigrationContext($this->migrationContext) + ->withEntityName($entity) + ->withFieldSourcePath('objectdata') + ->withSourceData($data) + ->withException($error) + ->build(ConvertUnserializedDataInvalidLog::class) + ); + + return null; } /** diff --git a/src/Profile/Shopware/Media/LocalMediaProcessor.php b/src/Profile/Shopware/Media/LocalMediaProcessor.php index 8c5a8a806..1c36cccb2 100644 --- a/src/Profile/Shopware/Media/LocalMediaProcessor.php +++ b/src/Profile/Shopware/Media/LocalMediaProcessor.php @@ -198,8 +198,7 @@ private function copyMediaFiles( 'source_path' => $sourcePath, 'media' => $mediaFile, ]) - ->withExceptionMessage($e->getMessage()) - ->withExceptionTrace($e->getTrace()) + ->withException($e) ->withEntityId($mediaId) ->build(RunExceptionLog::class) ); diff --git a/src/Profile/Shopware/Media/LocalOrderDocumentProcessor.php b/src/Profile/Shopware/Media/LocalOrderDocumentProcessor.php index 04b03eee1..1ba81fa89 100644 --- a/src/Profile/Shopware/Media/LocalOrderDocumentProcessor.php +++ b/src/Profile/Shopware/Media/LocalOrderDocumentProcessor.php @@ -129,14 +129,14 @@ private function copyMediaFiles( $this->loggingService->log( MigrationLogBuilder::fromMigrationContext($migrationContext) - ->withExceptionMessage($e->getMessage()) - ->withExceptionTrace($e->getTrace()) + ->withException($e) + ->withEntityName(MediaDefinition::ENTITY_NAME) + ->withEntityId($mediaId) ->withSourceData([ 'media_id' => $mediaId, 'source_path' => $sourcePath, 'media' => $mappedWorkload[$mediaId], ]) - ->withEntityId($mediaId) ->build(RunExceptionLog::class) ); } diff --git a/src/Profile/Shopware/Media/LocalProductDownloadProcessor.php b/src/Profile/Shopware/Media/LocalProductDownloadProcessor.php index b39751b6c..89632cdd3 100644 --- a/src/Profile/Shopware/Media/LocalProductDownloadProcessor.php +++ b/src/Profile/Shopware/Media/LocalProductDownloadProcessor.php @@ -138,8 +138,7 @@ private function copyMediaFiles( 'source_path' => $sourcePath, 'media' => $mappedWorkload[$mediaId], ]) - ->withExceptionMessage($e->getMessage()) - ->withExceptionTrace($e->getTrace()) + ->withException($e) ->withEntityId($mediaId) ->build(RunExceptionLog::class) ); diff --git a/src/Profile/Shopware6/Media/HttpOrderDocumentGenerationService.php b/src/Profile/Shopware6/Media/HttpOrderDocumentGenerationService.php index 8a2bc5867..c7bdf0e6a 100644 --- a/src/Profile/Shopware6/Media/HttpOrderDocumentGenerationService.php +++ b/src/Profile/Shopware6/Media/HttpOrderDocumentGenerationService.php @@ -13,6 +13,7 @@ use GuzzleHttp\Promise\Utils; use GuzzleHttp\Psr7\Response; use Shopware\Core\Checkout\Document\DocumentCollection; +use Shopware\Core\Content\Media\MediaDefinition; use Shopware\Core\Content\Media\MediaService; use Shopware\Core\Framework\Context; use Shopware\Core\Framework\DataAbstractionLayer\EntityRepository; @@ -88,8 +89,7 @@ public function process( $this->loggingService->log( MigrationLogBuilder::fromMigrationContext($migrationContext) - ->withExceptionMessage($exception->getMessage()) - ->withExceptionTrace($exception->getTrace()) + ->withException($exception) ->build(RunExceptionLog::class) ); @@ -286,10 +286,12 @@ private function handleFailedRequest( $failureUuids[] = $uuid; $mappedWorkload->setState(MediaProcessWorkloadStruct::ERROR_STATE); + $exception = $clientException ?? new \Exception('Unknown error occurred'); + $this->loggingService->log( MigrationLogBuilder::fromMigrationContext($migrationContext) - ->withExceptionMessage($clientException?->getMessage() ?? 'Unknown error occurred') - ->withExceptionTrace($clientException?->getTrace() ?? []) + ->withException($exception) + ->withEntityName(MediaDefinition::ENTITY_NAME) ->withSourceData($additionalData) ->withEntityId($uuid) ->build(MediaFileMissingLog::class) diff --git a/src/Resources/app/administration/src/module/swag-migration/page/wizard/swag-migration-wizard-page-profile-installation/swag-migration-wizard-page-profile-installation.html.twig b/src/Resources/app/administration/src/module/swag-migration/page/wizard/swag-migration-wizard-page-profile-installation/swag-migration-wizard-page-profile-installation.html.twig index d7ac8d301..56bccd579 100644 --- a/src/Resources/app/administration/src/module/swag-migration/page/wizard/swag-migration-wizard-page-profile-installation/swag-migration-wizard-page-profile-installation.html.twig +++ b/src/Resources/app/administration/src/module/swag-migration/page/wizard/swag-migration-wizard-page-profile-installation/swag-migration-wizard-page-profile-installation.html.twig @@ -112,11 +112,11 @@ {% block swag_migration_wizard_page_profile_installation_magento_available_version_list %}
- 1.9 2.0 2.1 2.2 - 2.3 + 2.3 + 2.4
{% endblock %} diff --git a/tests/Migration/Services/MigrationDataWriterTest.php b/tests/Migration/Services/MigrationDataWriterTest.php index 00d2523c4..db11cc5d5 100644 --- a/tests/Migration/Services/MigrationDataWriterTest.php +++ b/tests/Migration/Services/MigrationDataWriterTest.php @@ -55,6 +55,7 @@ use SwagMigrationAssistant\Migration\Gateway\Reader\ReaderRegistry; use SwagMigrationAssistant\Migration\History\LogGroupingService; use SwagMigrationAssistant\Migration\Logging\Log\RunExceptionLog; +use SwagMigrationAssistant\Migration\Logging\Log\WriteExceptionLog; use SwagMigrationAssistant\Migration\Logging\LoggingService; use SwagMigrationAssistant\Migration\Logging\LoggingServiceInterface; use SwagMigrationAssistant\Migration\Logging\SwagMigrationLoggingCollection; @@ -382,7 +383,7 @@ public function testHandleWriteException(): void $log = $this->loggingRepo->search(new Criteria(), $this->context)->getEntities()->first(); static::assertNotNull($log); - static::assertSame(RunExceptionLog::getCode(), $log->getCode()); + static::assertSame(WriteExceptionLog::getCode(), $log->getCode()); } #[DataProvider('requiredProperties')] diff --git a/tests/acceptance/snapshots/MigrationTest.spec.ts/linux/migration-log-sw5.txt b/tests/acceptance/snapshots/MigrationTest.spec.ts/linux/migration-log-sw5.txt index c317d98c7..339bf3bd1 100644 --- a/tests/acceptance/snapshots/MigrationTest.spec.ts/linux/migration-log-sw5.txt +++ b/tests/acceptance/snapshots/MigrationTest.spec.ts/linux/migration-log-sw5.txt @@ -735,7 +735,7 @@ Profile name: shopware55 Gateway name: local Created at: [timestamp] Entity: product -Exception message: SwagMigrationAssistant\Profile\Shopware\Converter\ProductConverter::getPrice(): Argument #1 ($priceData) must be of type array, null given, called in /home/runner/work/SwagMigrationAssistant/SwagMigrationAssistant/custom/plugins/SwagMigrationAssistant/src/Profile/Shopware/Converter/ProductConverter.php on line 383 +Exception message: SwagMigrationAssistant\Profile\Shopware\Converter\ProductConverter::getPrice(): Argument #1 ($priceData) must be of type array, null given, called in [path] Source data (JSON): { "id": "273", @@ -824,7 +824,7 @@ Gateway name: local Created at: [timestamp] Entity: product_translation Source path: objectdata -Exception message: Unserialization failed +Exception message: Unserialized data is not an array in [path] Source data (JSON): { "id": "170", @@ -838,6 +838,8 @@ Source data (JSON): "ordernumber": null, "objectlanguage": "2" } +Exception trace (JSON): +[trace] ----- Log Entry #10 ----- ID: [uuid] @@ -848,7 +850,7 @@ Gateway name: local Created at: [timestamp] Entity: product_translation Source path: objectdata -Exception message: Unserialization failed +Exception message: Unserialized data is not an array in [path] Source data (JSON): { "id": "172", @@ -862,6 +864,8 @@ Source data (JSON): "ordernumber": null, "objectlanguage": "2" } +Exception trace (JSON): +[trace] ----- Log Entry #11 ----- ID: [uuid] diff --git a/tests/acceptance/tests/MigrationTest.spec.ts b/tests/acceptance/tests/MigrationTest.spec.ts index 2d5a63eb9..5b27c1d38 100644 --- a/tests/acceptance/tests/MigrationTest.spec.ts +++ b/tests/acceptance/tests/MigrationTest.spec.ts @@ -279,6 +279,14 @@ test.describe('Migration Tests @migration @visual', () => { 'Exception trace (JSON):\n[trace]\n', ); + // remove exception paths + // (the regex replaces everything after the last occurrence of "in" in the exception message) + logString = logString.replaceAll(/(^Exception message:.*\bin\b )(?!.*\bin\b ).*/gm, '$1[path]'); + // some exceptions can also contain paths in the message itself (with the pattern "called in ...") + // so we need to replace them as well + // (the regex replaces everything after the last occurrence of "called in" in the message) + logString = logString.replaceAll(/^(Exception message:.*called in ).*$/gm, '$1[path]'); + expect(logString).toMatchSnapshot('migration-log-sw5.txt'); }); }); diff --git a/tests/integration/Migration/Validation/MigrationEntityValidationServiceTest.php b/tests/integration/Migration/Validation/MigrationEntityValidationServiceTest.php index 42cb722f3..01df02e77 100644 --- a/tests/integration/Migration/Validation/MigrationEntityValidationServiceTest.php +++ b/tests/integration/Migration/Validation/MigrationEntityValidationServiceTest.php @@ -317,7 +317,8 @@ public function testShouldLogWhenEntityHasInvalidOrMissingId(array $convertedDat $exceptionLog = array_values($logs)[0]; static::assertInstanceOf(MigrationValidationExceptionLog::class, $exceptionLog); - static::assertSame($expectedExceptionMessage, $exceptionLog->getExceptionMessage()); + static::assertNotNull($exceptionLog->getExceptionMessage()); + static::assertStringContainsString($expectedExceptionMessage, $exceptionLog->getExceptionMessage()); } /** diff --git a/tests/unit/Migration/Logging/Log/MigrationLogTest.php b/tests/unit/Migration/Logging/Log/MigrationLogTest.php index 49eefee96..bda9dc842 100644 --- a/tests/unit/Migration/Logging/Log/MigrationLogTest.php +++ b/tests/unit/Migration/Logging/Log/MigrationLogTest.php @@ -337,4 +337,102 @@ public static function logProvider(): \Generator 'userFixable' => false, ]; } + + /** + * @param array|null $exceptionTrace + * @param array $expectedExceptionTrace + */ + #[DataProvider('exceptionProvider')] + public function testLogEntryExceptions( + ?\Throwable $exception, + ?string $exceptionMessage, + ?array $exceptionTrace, + string $expectedExceptionMessage, + ?array $expectedExceptionTrace, + ): void { + $connection = new SwagMigrationConnectionEntity(); + $connection->setProfileName(Shopware54Profile::PROFILE_NAME); + $connection->setGatewayName(DummyLocalGateway::GATEWAY_NAME); + + $context = new MigrationContext( + $connection, + new Shopware54Profile(), + new DummyLocalGateway(), + null, + Uuid::randomHex(), + ); + + $builder = MigrationLogBuilder::fromMigrationContext($context); + + if ($exception !== null) { + $builder = $builder->withException($exception); + } + + if ($exceptionMessage !== null) { + $builder = $builder->withExceptionMessage($exceptionMessage); + } + + if ($exceptionTrace !== null) { + $builder = $builder->withExceptionTrace($exceptionTrace); + } + + $logEntry = $builder->build(RunExceptionLog::class); + + static::assertInstanceOf(RunExceptionLog::class, $logEntry); + static::assertSame($expectedExceptionMessage, $logEntry->getExceptionMessage()); + static::assertSame($expectedExceptionTrace, $logEntry->getExceptionTrace()); + } + + public static function exceptionProvider(): \Generator + { + $exception = new \RuntimeException('Runtime exception occurred'); + $file = $exception->getFile(); + $line = $exception->getLine(); + $trace = $exception->getTrace(); + + // unset args from trace for comparison, as they are removed in the log entry + foreach ($trace as &$traceEntry) { + unset($traceEntry['args']); + } + + yield 'with exception' => [ + 'exception' => $exception, + 'exceptionMessage' => null, + 'exceptionTrace' => null, + 'expectedExceptionMessage' => 'Runtime exception occurred in ' . $file . ':' . $line, + 'expectedExceptionTrace' => $trace, + ]; + + yield 'with exception message and trace' => [ + 'exception' => null, + 'exceptionMessage' => 'Test2', + 'exceptionTrace' => [['test' => 'trace']], + 'expectedExceptionMessage' => 'Test2', + 'expectedExceptionTrace' => [['test' => 'trace']], + ]; + + yield 'with exception and message' => [ + 'exception' => $exception, + 'exceptionMessage' => 'Test4', + 'exceptionTrace' => null, + 'expectedExceptionMessage' => 'Test4', + 'expectedExceptionTrace' => $trace, + ]; + + yield 'with exception and trace' => [ + 'exception' => $exception, + 'exceptionMessage' => null, + 'exceptionTrace' => [['test' => 'trace2']], + 'expectedExceptionMessage' => 'Runtime exception occurred in ' . $file . ':' . $line, + 'expectedExceptionTrace' => [['test' => 'trace2']], + ]; + + yield 'with exception, message and trace' => [ + 'exception' => $exception, + 'exceptionMessage' => 'Test5', + 'exceptionTrace' => [['test' => 'trace3']], + 'expectedExceptionMessage' => 'Test5', + 'expectedExceptionTrace' => [['test' => 'trace3']], + ]; + } }