diff --git a/core/BackgroundJobs/PreviewMigrationJob.php b/core/BackgroundJobs/PreviewMigrationJob.php index a9a5c9f773c..5a8f9fffbcc 100644 --- a/core/BackgroundJobs/PreviewMigrationJob.php +++ b/core/BackgroundJobs/PreviewMigrationJob.php @@ -19,6 +19,7 @@ use OCP\IAppConfig; use OCP\IConfig; use OCP\IDBConnection; use Override; +use Psr\Log\LoggerInterface; class PreviewMigrationJob extends TimedJob { private string $previewRootPath; @@ -30,6 +31,7 @@ class PreviewMigrationJob extends TimedJob { private readonly IDBConnection $connection, private readonly IRootFolder $rootFolder, private readonly PreviewMigrationService $migrationService, + private readonly LoggerInterface $logger, ) { parent::__construct($time); @@ -95,11 +97,23 @@ class PreviewMigrationJob extends TimedJob { } foreach ($fileIds as $fileId) { - $this->migrationService->migrateFileId($fileId, flatPath: false); + try { + $this->migrationService->migrateFileId($fileId, flatPath: false); + } catch (\Exception $e) { + $this->logger->error('Failed to migrate preview with fileId: ' . $fileId . ' (hierarchical file structure)', [ + 'exception' => $e, + ]); + } } foreach ($flatFileIds as $fileId) { - $this->migrationService->migrateFileId($fileId, flatPath: true); + try { + $this->migrationService->migrateFileId($fileId, flatPath: true); + } catch (\Exception $e) { + $this->logger->error('Failed to migrate preview with fileId: ' . $fileId . ' (legacy file structure)', [ + 'exception' => $e, + ]); + } } return $foundPreview; } diff --git a/lib/private/Preview/PreviewMigrationService.php b/lib/private/Preview/PreviewMigrationService.php index 220a52baddb..555bd388447 100644 --- a/lib/private/Preview/PreviewMigrationService.php +++ b/lib/private/Preview/PreviewMigrationService.php @@ -93,8 +93,9 @@ class PreviewMigrationService { ->where($qb->expr()->eq('fileid', $qb->createNamedParameter($fileId))) ->setMaxResults(1); - $result = $qb->executeQuery(); - $result = $result->fetchAssociative(); + $cursor = $qb->executeQuery(); + $result = $cursor->fetchAssociative(); + $cursor->closeCursor(); if ($result !== false) { foreach ($previewFiles as $previewFile) { @@ -108,7 +109,11 @@ class PreviewMigrationService { $preview->generateId(); try { $preview = $this->previewMapper->insert($preview); - } catch (Exception) { + } catch (Exception $e) { + if ($e->getReason() !== Exception::REASON_UNIQUE_CONSTRAINT_VIOLATION) { + throw $e; + } + $delete = $this->connection->getQueryBuilder(); // We already have this preview in the preview table, skip $delete->delete('filecache') @@ -180,7 +185,11 @@ class PreviewMigrationService { break; } - $folder = $this->appData->getFolder($current); + try { + $folder = $this->appData->getFolder($current); + } catch (NotFoundException) { + break; + } if (count($folder->getDirectoryListing()) !== 0) { break; } diff --git a/tests/lib/Preview/PreviewMigrationJobTest.php b/tests/lib/Preview/PreviewMigrationJobTest.php index 2f769d79d24..fe9cd968799 100644 --- a/tests/lib/Preview/PreviewMigrationJobTest.php +++ b/tests/lib/Preview/PreviewMigrationJobTest.php @@ -131,7 +131,8 @@ class PreviewMigrationJobTest extends TestCase { $this->previewMapper, $this->storageFactory, Server::get(IAppDataFactory::class), - ) + ), + $this->logger, ); $this->invokePrivate($job, 'run', [[]]); $this->assertEquals(0, count($this->previewAppData->getDirectoryListing())); @@ -168,7 +169,8 @@ class PreviewMigrationJobTest extends TestCase { $this->previewMapper, $this->storageFactory, Server::get(IAppDataFactory::class), - ) + ), + $this->logger, ); $this->invokePrivate($job, 'run', [[]]); $this->assertEquals(0, count($this->previewAppData->getDirectoryListing())); @@ -213,7 +215,8 @@ class PreviewMigrationJobTest extends TestCase { $this->previewMapper, $this->storageFactory, Server::get(IAppDataFactory::class), - ) + ), + $this->logger, ); $this->invokePrivate($job, 'run', [[]]); $previews = iterator_to_array($this->previewMapper->getAvailablePreviewsForFile(5));