From c00acd1abafba620319c8d08c3d5d5f15493b86f Mon Sep 17 00:00:00 2001 From: Jonas Date: Mon, 27 Apr 2026 17:31:48 +0200 Subject: [PATCH] fix(AmazonS3): pass S3 error messages through to the frontend * S3Exception to NotPermittedException in Storage/AmazonS3::writeStream() * NotPermittedException to Forbidden in Storage/Common::copyFromStorage() Improves error messages on move/copy operations when bucket quota exceeded Fixes: #58801 Signed-off-by: Jonas --- apps/files_external/lib/Lib/Storage/AmazonS3.php | 11 ++++++++++- lib/private/Files/Storage/Common.php | 4 ++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/apps/files_external/lib/Lib/Storage/AmazonS3.php b/apps/files_external/lib/Lib/Storage/AmazonS3.php index 583981d3cb4a9..9986270a931cc 100644 --- a/apps/files_external/lib/Lib/Storage/AmazonS3.php +++ b/apps/files_external/lib/Lib/Storage/AmazonS3.php @@ -19,6 +19,7 @@ use OCP\Constants; use OCP\Files\FileInfo; use OCP\Files\IMimeTypeDetector; +use OCP\Files\NotPermittedException; use OCP\ICache; use OCP\ICacheFactory; use OCP\ITempManager; @@ -790,7 +791,15 @@ public function writeStream(string $path, $stream, ?int $size = null): int { } $path = $this->normalizePath($path); - $this->writeObject($path, $stream, $this->mimeDetector->detectPath($path)); + try { + $this->writeObject($path, $stream, $this->mimeDetector->detectPath($path)); + } catch (S3Exception $exception) { + $this->logger->error($exception->getMessage(), [ + 'app' => 'files_external', + 'exception' => $exception, + ]); + throw new NotPermittedException($exception->getMessage(), $exception->getCode(), $exception); + } $this->invalidateCache($path); return $size; diff --git a/lib/private/Files/Storage/Common.php b/lib/private/Files/Storage/Common.php index d6462fe245b2e..51fbffdf15392 100644 --- a/lib/private/Files/Storage/Common.php +++ b/lib/private/Files/Storage/Common.php @@ -29,6 +29,7 @@ use OCP\Files\GenericFileException; use OCP\Files\IFilenameValidator; use OCP\Files\InvalidPathException; +use OCP\Files\NotPermittedException; use OCP\Files\Storage\IConstructableStorage; use OCP\Files\Storage\ILockingStorage; use OCP\Files\Storage\IStorage; @@ -521,6 +522,9 @@ public function copyFromStorage(IStorage $sourceStorage, string $sourceInternalP try { $this->writeStream($targetInternalPath, $source); $result = true; + } catch (NotPermittedException $e) { + Server::get(LoggerInterface::class)->warning('Failed to copy stream to storage', ['exception' => $e]); + throw new ForbiddenException($e->getMessage(), false, $e); } catch (\Exception $e) { Server::get(LoggerInterface::class)->warning('Failed to copy stream to storage', ['exception' => $e]); }