From 4722f56778cc6a590a91114773dd76a6e3a6b16a Mon Sep 17 00:00:00 2001 From: Carl Schwan Date: Tue, 10 Feb 2026 12:32:09 +0100 Subject: [PATCH] fix(preview): Handle unique constraints Signed-off-by: Carl Schwan --- lib/private/Preview/Generator.php | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/lib/private/Preview/Generator.php b/lib/private/Preview/Generator.php index a923321faa0..e68120338ef 100644 --- a/lib/private/Preview/Generator.php +++ b/lib/private/Preview/Generator.php @@ -11,6 +11,7 @@ use OC\Preview\Db\Preview; use OC\Preview\Db\PreviewMapper; use OC\Preview\Storage\PreviewFile; use OC\Preview\Storage\StorageFactory; +use OCP\DB\Exception as DBException; use OCP\EventDispatcher\IEventDispatcher; use OCP\Files\File; use OCP\Files\InvalidPathException; @@ -331,9 +332,26 @@ class Generator { $maxWidth = $this->config->getSystemValueInt('preview_max_x', 4096); $maxHeight = $this->config->getSystemValueInt('preview_max_y', 4096); - return $this->generateProviderPreview($file, $maxWidth, $maxHeight, false, true, $mimeType, $version); + try { + return $this->generateProviderPreview($file, $maxWidth, $maxHeight, false, true, $mimeType, $version); + } catch (DBException $e) { + if ($e->getReason() === DBException::REASON_UNIQUE_CONSTRAINT_VIOLATION) { + // Fetch again, likely two HTTP requests for the same file were done around the same time + [$file->getId() => $previews] = $this->previewMapper->getAvailablePreviews([$file->getId()]); + foreach ($previews as $preview) { + if ($preview->isMax() && ($version === $preview->getVersion())) { + return $preview; + } + } + } + throw $e; + } } + /** + * @throws DBException + * @throws NotFoundException + */ private function generateProviderPreview(File $file, int $width, int $height, bool $crop, bool $max, string $mimeType, ?string $version): Preview { $previewProviders = $this->previewManager->getProviders(); foreach ($previewProviders as $supportedMimeType => $providers) { @@ -551,7 +569,7 @@ class Generator { * @throws InvalidPathException * @throws NotFoundException * @throws NotPermittedException - * @throws \OCP\DB\Exception + * @throws DBException */ public function savePreview(Preview $previewEntry, IImage $preview): Preview { // we need to save to DB first