From 1bfc656ddd7ab5d602a49cbc86b3e4ab903e1a79 Mon Sep 17 00:00:00 2001 From: Mats Svensson Date: Mon, 20 Nov 2023 14:20:57 +0100 Subject: [PATCH] [WIP] intercept errors when API connection fails, logging, messages --- .github/workflows/ci.yml | 4 +- .../Command/UpdateQbankFileStatusCommand.php | 9 +++ Classes/Controller/ManagementController.php | 31 +++++++++- .../MediaUsageReporterDataHandlerHook.php | 56 +++++++++++++------ Classes/Repository/AbstractRepository.php | 14 ++++- Classes/Service/QbankService.php | 13 +++++ Classes/Utility/MessageUtility.php | 46 +++++++++++++++ .../Private/Language/locallang_mod_qbank.xlf | 3 + Resources/Private/Partials/ApiStatus.html | 10 ++++ .../Private/Templates/Management/List.html | 2 + .../Templates/Management/Mappings.html | 8 ++- .../Templates/Management/Overview.html | 2 + 12 files changed, 176 insertions(+), 22 deletions(-) create mode 100644 Classes/Utility/MessageUtility.php create mode 100644 Resources/Private/Partials/ApiStatus.html diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8363921..b048dc6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -117,12 +117,12 @@ jobs: run: | composer require --no-progress typo3/minimal:"$TYPO3" composer show - - if: "matrix.composer-dependencies == 'lowest'" + - if: matrix.composer-dependencies == 'lowest' name: "Install lowest dependencies with composer" run: | composer update --no-ansi --no-interaction --no-progress --with-dependencies --prefer-lowest composer show - - if: "matrix.composer-dependencies == 'highest'" + - if: matrix.composer-dependencies == 'highest' name: "Install highest dependencies with composer" run: | composer update --no-ansi --no-interaction --no-progress --with-dependencies diff --git a/Classes/Command/UpdateQbankFileStatusCommand.php b/Classes/Command/UpdateQbankFileStatusCommand.php index 4c99553..a607f45 100644 --- a/Classes/Command/UpdateQbankFileStatusCommand.php +++ b/Classes/Command/UpdateQbankFileStatusCommand.php @@ -115,6 +115,15 @@ protected function execute(InputInterface $input, OutputInterface $output) continue; } + } catch (\Throwable $th) { + $io->writeln( + sprintf( + 'QBank file [%s] was not found: "%s"', + $file['tx_qbank_id'], + $th->getMessage() + ) + ); + break; } $remoteUpdate = (int)$media->getUpdated()->getTimestamp(); diff --git a/Classes/Controller/ManagementController.php b/Classes/Controller/ManagementController.php index 4732271..2e0e934 100644 --- a/Classes/Controller/ManagementController.php +++ b/Classes/Controller/ManagementController.php @@ -33,6 +33,7 @@ use TYPO3\CMS\Core\Imaging\Icon; use TYPO3\CMS\Core\Imaging\IconFactory; use TYPO3\CMS\Core\Localization\LanguageService; +use TYPO3\CMS\Core\Log\LogManager; use TYPO3\CMS\Core\Messaging\AbstractMessage; use TYPO3\CMS\Core\Page\JavaScriptModuleInstruction; use TYPO3\CMS\Core\Page\PageRenderer; @@ -90,7 +91,24 @@ public function initializeAction(): void */ protected function initializeView(): void { + $apiStatus = []; + try { + $checkStatus = $this->qbankService->fetchMediaProperties(); + } catch (\Throwable $th) { + $apiStatus = [ + 'errorMessage' => $th->getMessage(), + 'errorCode' => $th->getCode(), + ]; + $logger = GeneralUtility::makeInstance(LogManager::class)->getLogger(__CLASS__); + $logger->error( + sprintf( + 'Failed to connect to QBank API: "%s"', + $th->getMessage() + ) + ); + } $this->moduleTemplate->assignMultiple([ + 'apiStatus' => $apiStatus, 'dateFormat' => $GLOBALS['TYPO3_CONF_VARS']['SYS']['ddmmyy'], 'timeFormat' => $GLOBALS['TYPO3_CONF_VARS']['SYS']['hhmm'], 'dateTimeFormat' => @@ -192,7 +210,11 @@ protected function overviewAction(): ResponseInterface { $this->generateDropdownMenu('overview'); $this->generateButtons('overview'); - $properties = $this->qbankService->fetchMediaProperties(); + try { + $properties = $this->qbankService->fetchMediaProperties(); + } catch (\Throwable $th) { + $properties = []; + } $this->moduleTemplate->assign('properties', $properties); return $this->moduleTemplate->renderResponse('Management/Overview'); } @@ -206,9 +228,14 @@ protected function mappingsAction(): ResponseInterface $this->generateButtons('mappings'); $mappingRepository = GeneralUtility::makeInstance(MappingRepository::class); $mappings = $mappingRepository->findAll(); + try { + $mediaProperties = $this->qbankService->fetchMediaProperties(); + } catch (\Throwable $th) { + $mediaProperties = []; + } $this->moduleTemplate->assignMultiple([ 'mappings' => $mappings, - 'mediaProperties' => $this->qbankService->fetchMediaProperties(), + 'mediaProperties' => $mediaProperties, 'fileProperties' => PropertyUtility::getFileProperties(), ]); return $this->moduleTemplate->renderResponse('Management/Mappings'); diff --git a/Classes/Hook/MediaUsageReporterDataHandlerHook.php b/Classes/Hook/MediaUsageReporterDataHandlerHook.php index 9fe2676..81676f0 100644 --- a/Classes/Hook/MediaUsageReporterDataHandlerHook.php +++ b/Classes/Hook/MediaUsageReporterDataHandlerHook.php @@ -5,7 +5,9 @@ namespace Pixelant\Qbank\Hook; use Pixelant\Qbank\Service\QbankService; +use Pixelant\Qbank\Utility\MessageUtility; use TYPO3\CMS\Core\DataHandling\DataHandler; +use TYPO3\CMS\Core\Type\ContextualFeedbackSeverity; use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Core\Utility\MathUtility; @@ -26,9 +28,20 @@ public function processDatamap_afterAllOperations(DataHandler $dataHandler): voi foreach ($dataHandler->datamap['sys_file_reference'] ?? [] as $id => $record) { // Only process new records if (!MathUtility::canBeInterpretedAsInteger($id)) { - GeneralUtility::makeInstance(QbankService::class)->reportMediaUsageInFileReference( - $dataHandler->substNEWwithIDs[$id] - ); + try { + GeneralUtility::makeInstance(QbankService::class)->reportMediaUsageInFileReference( + $dataHandler->substNEWwithIDs[$id] + ); + } catch (\Throwable $th) { + MessageUtility::enqueueMessage( + sprintf( + 'Media usage was not reported to QBank: "%s"', + $th->getMessage() + ), + 'Connection to QBank API failed', + ContextualFeedbackSeverity::ERROR + ); + } } } } @@ -52,22 +65,33 @@ public function processCmdmap_preProcess( DataHandler $dataHandler ): void { if ($table === 'sys_file_reference') { - switch ($command) { - case 'move': - /** @var QbankService $qbankService */ - $qbankService = GeneralUtility::makeInstance(QbankService::class); - $qbankService->removeMediaUsageInFileReference($id); - $qbankService->reportMediaUsageInFileReference($id); + try { + switch ($command) { + case 'move': + /** @var QbankService $qbankService */ + $qbankService = GeneralUtility::makeInstance(QbankService::class); + $qbankService->removeMediaUsageInFileReference($id); + $qbankService->reportMediaUsageInFileReference($id); - break; - case 'delete': - GeneralUtility::makeInstance(QbankService::class)->removeMediaUsageInFileReference($id); + break; + case 'delete': + GeneralUtility::makeInstance(QbankService::class)->removeMediaUsageInFileReference($id); - break; - case 'undelete': - GeneralUtility::makeInstance(QbankService::class)->reportMediaUsageInFileReference($id); + break; + case 'undelete': + GeneralUtility::makeInstance(QbankService::class)->reportMediaUsageInFileReference($id); - break; + break; + } + } catch (\Throwable $th) { + MessageUtility::enqueueMessage( + sprintf( + 'Media usage was not reported to QBank: "%s"', + $th->getMessage() + ), + 'Connection to QBank API failed', + ContextualFeedbackSeverity::ERROR + ); } } } diff --git a/Classes/Repository/AbstractRepository.php b/Classes/Repository/AbstractRepository.php index bc0cfa5..21c2207 100644 --- a/Classes/Repository/AbstractRepository.php +++ b/Classes/Repository/AbstractRepository.php @@ -6,7 +6,9 @@ use Pixelant\Qbank\Utility\QbankUtility; use QBNK\QBank\API\QBankApi; +use TYPO3\CMS\Core\Log\LogManager; use TYPO3\CMS\Core\SingletonInterface; +use TYPO3\CMS\Core\Utility\GeneralUtility; class AbstractRepository implements SingletonInterface { @@ -17,6 +19,16 @@ class AbstractRepository implements SingletonInterface public function __construct() { - $this->api = QbankUtility::getApi(); + try { + $this->api = QbankUtility::getApi(); + } catch (\Throwable $th) { + $logger = GeneralUtility::makeInstance(LogManager::class)->getLogger(__CLASS__); + $logger->error( + sprintf( + 'Failed to connect to QBank API: "%s"', + $th->getMessage() + ) + ); + } } } diff --git a/Classes/Service/QbankService.php b/Classes/Service/QbankService.php index a2a6147..45303e9 100644 --- a/Classes/Service/QbankService.php +++ b/Classes/Service/QbankService.php @@ -20,6 +20,7 @@ use Pixelant\Qbank\Service\Event\FilePropertyChangeEvent; use Pixelant\Qbank\Service\Event\FileReferenceUrlEvent; use Pixelant\Qbank\Service\Event\ResolvePageTitleEvent; +use Pixelant\Qbank\Utility\MessageUtility; use Pixelant\Qbank\Utility\PropertyUtility; use Pixelant\Qbank\Utility\QbankUtility; use QBNK\QBank\API\Exception\RequestException; @@ -37,6 +38,7 @@ use TYPO3\CMS\Core\Resource\ResourceFactory; use TYPO3\CMS\Core\SingletonInterface; use TYPO3\CMS\Core\Site\SiteFinder; +use TYPO3\CMS\Core\Type\ContextualFeedbackSeverity; use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Core\Utility\StringUtility; @@ -252,6 +254,17 @@ public function synchronizeMetadata(int $fileId): void 1625149218 ); } + } catch (\Throwable $th) { + MessageUtility::enqueueMessage( + sprintf( + 'Could not synchronize metadata for file [%s]: "%s"', + $fileId, + $th->getMessage() + ), + 'QBank', + ContextualFeedbackSeverity::ERROR + ); + return; } $metaDataMappings = GeneralUtility::makeInstance(MappingRepository::class)->findAllAsKeyValuePairs(false); diff --git a/Classes/Utility/MessageUtility.php b/Classes/Utility/MessageUtility.php new file mode 100644 index 0000000..a6b2276 --- /dev/null +++ b/Classes/Utility/MessageUtility.php @@ -0,0 +1,46 @@ +getPropertyFromAspect('backend.user', 'id'); + + if ($beUserId > 0) { + $flashMessageService = GeneralUtility::makeInstance(FlashMessageService::class); + $notificationQueue = $flashMessageService->getMessageQueueByIdentifier( + FlashMessageQueue::NOTIFICATION_QUEUE + ); + $flashMessage = GeneralUtility::makeInstance( + FlashMessage::class, + $message, + $title, + $severity, + true + ); + $notificationQueue->enqueue($flashMessage); + } + + $logger = GeneralUtility::makeInstance(LogManager::class)->getLogger(__CLASS__); + $logger->error($message . PHP_EOL . $title); + } +} diff --git a/Resources/Private/Language/locallang_mod_qbank.xlf b/Resources/Private/Language/locallang_mod_qbank.xlf index ad44eaf..b800dba 100644 --- a/Resources/Private/Language/locallang_mod_qbank.xlf +++ b/Resources/Private/Language/locallang_mod_qbank.xlf @@ -21,6 +21,9 @@ TYPO3 property + + Connection to QBank API failed + diff --git a/Resources/Private/Partials/ApiStatus.html b/Resources/Private/Partials/ApiStatus.html new file mode 100644 index 0000000..67f0df5 --- /dev/null +++ b/Resources/Private/Partials/ApiStatus.html @@ -0,0 +1,10 @@ + + + diff --git a/Resources/Private/Templates/Management/List.html b/Resources/Private/Templates/Management/List.html index 2823c2a..acb04c4 100644 --- a/Resources/Private/Templates/Management/List.html +++ b/Resources/Private/Templates/Management/List.html @@ -11,6 +11,8 @@

+ + diff --git a/Resources/Private/Templates/Management/Mappings.html b/Resources/Private/Templates/Management/Mappings.html index 5e1befe..da75491 100644 --- a/Resources/Private/Templates/Management/Mappings.html +++ b/Resources/Private/Templates/Management/Mappings.html @@ -10,6 +10,9 @@

+ + + @@ -31,7 +34,10 @@

- + + + ({mapping.source_property}) +

+ +

{propertyType.name} - [{propertyType.systemName}] - {propertyType.description} - {propertyType.dataTypeId}