From d6e4c6fc87dca4182f4cc91e293944093b1b686f Mon Sep 17 00:00:00 2001 From: Andras Timar Date: Tue, 8 Sep 2026 20:46:06 +0200 Subject: [PATCH] fix(wopi): report a locked file as 423, not 500 When putContent() throws LockedException the file is locked by another operation and we have written nothing. Answering 500 says the server is broken, which it isn't, and it buries a routine, self-resolving condition in the error logs. It also misleads the editor. Collabora Online cannot tell a genuine fault from a refusal, so after the failed upload it asks for CheckFileInfo to work out whether the document in storage is still the one it knows. A 423 lets it see the upload for what it was and retry once the lock clears. 423 is what this controller already answers with when the lock manager reports a file locked in lock() and refreshLock(); use it on the write path too. Do not use 409: in WOPI that means the document changed in storage, and Collabora Online reads it that way. It would put a conflict dialog in front of the user, asking them to discard their work or overwrite a file that nobody has touched. Signed-off-by: Andras Timar --- lib/Controller/WopiController.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/Controller/WopiController.php b/lib/Controller/WopiController.php index 23493f122d..8c0ef1aedb 100644 --- a/lib/Controller/WopiController.php +++ b/lib/Controller/WopiController.php @@ -665,7 +665,10 @@ public function putFile( $this->wrappedFilesystemOperation($wopi, fn () => $file->putContent($content)); } catch (LockedException $e) { $this->logger->error($e->getMessage(), ['exception' => $e]); - return new JSONResponse(['message' => 'File locked'], Http::STATUS_INTERNAL_SERVER_ERROR); + // The file is locked by another operation and we wrote nothing. + // Report it as such, so the client can retry rather than treat + // this as a server fault or as a change behind its back. + return new JSONResponse(['message' => 'File locked'], Http::STATUS_LOCKED); } if ($wopi->hasTemplateId()) { @@ -808,7 +811,8 @@ public function postFile( try { $this->wrappedFilesystemOperation($wopi, fn () => $file->putContent($content)); } catch (LockedException) { - return new JSONResponse(['message' => 'File locked'], Http::STATUS_INTERNAL_SERVER_ERROR); + // As in putFile(): nothing was written, so this is not a server fault. + return new JSONResponse(['message' => 'File locked'], Http::STATUS_LOCKED); } // epub is exception (can be uploaded but not opened so don't try to get access token)