Repository navigation
fix(chat): Mark voice message as failed when its upload fails - #2740
Open
ToteMeiSter wants to merge 2 commits into
Open
ToteMeiSter wants to merge 2 commits into
ToteMeiSter wants to merge 2 commits into
Conversation
When uploading a voice message failed, only an alert was shown. The temporary message stayed in the "sending" state, and as "Resend" and "Delete" are only offered for failed messages, it could neither be resent nor removed until it was marked as failed after 12 hours. Mark the temporary message as failed right away, in the database and in the open chat, so the existing "Resend" and "Delete" actions work. When resending, show and store the voice message as sending again. Before, it was shown as failed during the new upload and was removed from the database, so a second failure could not be kept. Signed-off-by: Krainov Gleb <krajnov.g@kontentplus.ru> Assisted-by: Claude Code:claude-opus-5-5
A failed upload of a voice message showed "Unknown error occurred". Show the description of the upload error instead, as the share view already does for other files. Signed-off-by: Krainov Gleb <krajnov.g@kontentplus.ru> Assisted-by: Claude Code:claude-opus-5-5
This was referenced Oct 3, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
When uploading a voice message fails, the message stays in the "sending" state. It can neither be resent nor
deleted until it is marked as failed after 12 hours. This PR marks it as failed right away, so the existing
"Resend" and "Delete" actions are available.
No open issue covers this. Related, closed: #741 (missing error message for a failed voice message upload),
#827 (upload error message).
Root cause
BaseChatViewController.shareVoiceMessage()creates a temporary message (isTemporary = true, stored in Realm)and calls
upload(_:)with itsreferenceId.ChatFileUploader.upload(_:)throws,upload(_:)only callspresentUploadError(_:for:).The temporary message is neither marked as failed nor removed.
sendingFailed || isOfflineMessage(
ChatViewControllercontext menu;BaseChatViewController.didPressDelete(for:)).isOfflineMessageis never setfor voice messages.
NCChatController.getTemporaryMessages(), which marks temporary messages older than 12 hoursas failed when the chat is opened.
.uploadFailed(including network errors such as-1005/-1009) the alert says "Unknown error occurred",because
presentUploadErrorfalls through todefault.Changes
Two commits,
BaseChatViewController.swiftonly (+ a unit test):fix(chat): Mark voice message as failed when its upload failscatchofupload(_:), a newmarkTemporaryMessageAsFailed(referenceId:)setssendingFailed = trueand
isOfflineMessage = false:referenceId = %@ AND isTemporary = true), the same wayNCChatController.sendChatMessagedoes it after failed retries;modifyMessageWith(referenceId:). Messages that areno longer temporary are left untouched.
referenceId(contacts) are not affected.didPressResend(for:), voice branch: the message is reset to sending (sendingFailed = false,isOfflineMessage = false) and stored again before the new upload. Before, it removed the stored message andre-appended the same object, still flagged as failed: the cell showed "failed" during the new upload,
"Resend" stayed available (a second tap would send the voice message twice), and a second failure was lost
after reopening the chat. This path was only reachable after 12 hours so far; with this fix it is the main one.
fix(chat): Show the reason when uploading a voice message fails.uploadFailedwith a non-empty description, the alert shows that description instead of"Unknown error occurred". This is what
ShareConfirmationViewController.message(for:)already does.No new strings. The second commit can be dropped if this is not wanted.
Behaviour per error
.uploadFailed(network error, other HTTP status).quotaExceeded(507),.tooManyRequests(429).attachmentFolderUnavailable.destinationUnavailable.shareFailed.shareFailedmeans the file is already on the server, but posting it into the conversation failed. The messageis still marked as failed:
referenceIdand replaces the temporary one (NCChatController.storeMessages,ChatViewController.appendReceivedMessagesAndComputeTableViewUpdate), regardless ofsendingFailed.A duplicate is only possible if the user presses "Resend" before that.
Not changed
NCChatController.send(_:)also uploads voice messages and only logs a failure. It is only reached fromNCRoomsManager.resendOfflineMessages, which selectsisOfflineMessage = true. That flag is never set for voicemessages, so this path is not changed.
new upload is still running,
getTemporaryMessages()marks it failed early (existing rule, not changed).Overlap with #2705
#2705 (draft) changes
BaseChatViewController.swift, but notdidPressResend(for:),upload(_:)orpresentUploadError(_:for:). Its nearest hunk isdidPressDelete(for:), about 100 lines belowdidPressResend.A textual conflict is not expected; if #2705 is merged first, a rebase should apply cleanly.
#2705 also changes the context menu
Deletecondition for grouped files. Single voice messages keepsendingFailed || isOfflineMessage, so this fix still enables "Delete" for them.How to test
Not built or run locally (no Xcode available). Build and tests: CI only.
Unit tests in
UnitBaseChatViewControllerTest(database part only; the open-chat part needs a loaded table):testMarkTemporaryMessageAsFailed— a temporary message is marked as failed, a received message with the samereferenceIdis not;testMarkTemporaryMessageAsFailedIgnoresReceivedMessage— only a received message exists, it stays unchanged.Manual, on a device (expected result, not verified):
message is removed.
chat still shows it as failed.
SwiftLint (
swiftlint lint --quiet, 0.65.1): no new warnings or errors.AI disclosure
This change was prepared with AI assistance (Claude Code, model claude-opus-5-5): code reading, the fix, the test
and this description. Commits carry
Assisted-by: Claude Code:claude-opus-5-5.The change was reviewed by the author. It was not built or tested on a device (no Xcode available).
🤖 Generated with Claude Code