Updated the GroupLeavingJob to succeed for certain error cases

pull/751/head
Morgan Pretty 1 year ago
parent 1ba060b7f0
commit 44f8b7f59d

@ -58,67 +58,75 @@ public enum GroupLeavingJob: JobExecutor {
.receive(on: queue)
.sinkUntilComplete(
receiveCompletion: { result in
switch result {
case .failure:
Storage.shared.writeAsync { db in
try Interaction
.filter(id: job.interactionId)
.updateAll(
db,
[
Interaction.Columns.variant
.set(to: Interaction.Variant.infoClosedGroupCurrentUserErrorLeaving),
Interaction.Columns.body.set(to: "group_unable_to_leave".localized())
]
)
let failureChanges: [ConfigColumnAssignment] = [
Interaction.Columns.variant
.set(to: Interaction.Variant.infoClosedGroupCurrentUserErrorLeaving),
Interaction.Columns.body.set(to: "group_unable_to_leave".localized())
]
let successfulChanges: [ConfigColumnAssignment] = [
Interaction.Columns.variant
.set(to: Interaction.Variant.infoClosedGroupCurrentUserLeft),
Interaction.Columns.body.set(to: "GROUP_YOU_LEFT".localized())
]
// Handle the appropriate response
Storage.shared.writeAsync { db in
// If it failed due to one of these errors then clear out any associated data (as somehow
// the 'SessionThread' exists but not the data required to send the 'MEMBER_LEFT' message
// which would leave the user in a state where they can't leave the group)
let errorsToSucceed: [MessageSenderError] = [
.invalidClosedGroupUpdate,
.noKeyPair
]
let shouldSucceed: Bool = {
switch result {
case .failure(let error as MessageSenderError): return errorsToSucceed.contains(error)
case .failure: return false
default: return true
}
success(job, false)
case .finished:
Storage.shared.writeAsync { db in
// Update the group (if the admin leaves the group is disbanded)
let currentUserPublicKey: String = getUserHexEncodedPublicKey(db)
let wasAdminUser: Bool = GroupMember
.filter(GroupMember.Columns.groupId == threadId)
.filter(GroupMember.Columns.profileId == currentUserPublicKey)
.filter(GroupMember.Columns.role == GroupMember.Role.admin)
.isNotEmpty(db)
if wasAdminUser {
try GroupMember
.filter(GroupMember.Columns.groupId == threadId)
.deleteAll(db)
}
else {
try GroupMember
.filter(GroupMember.Columns.groupId == threadId)
.filter(GroupMember.Columns.profileId == currentUserPublicKey)
.deleteAll(db)
}
// Update the transaction
try Interaction
.filter(id: interactionId)
.updateAll(
db,
[
Interaction.Columns.variant
.set(to: Interaction.Variant.infoClosedGroupCurrentUserLeft),
Interaction.Columns.body.set(to: "GROUP_YOU_LEFT".localized())
]
)
// Clear out the group info as needed
try ClosedGroup.removeKeysAndUnsubscribe(
db,
threadId: threadId,
removeGroupData: details.deleteThread,
calledFromConfigHandling: false
)
}
success(job, false)
}()
// Update the transaction
try Interaction
.filter(id: interactionId)
.updateAll(
db,
(shouldSucceed ? successfulChanges : failureChanges)
)
// If we succeed in leaving then we should try to clear the group data
guard shouldSucceed else { return }
// Update the group (if the admin leaves the group is disbanded)
let currentUserPublicKey: String = getUserHexEncodedPublicKey(db)
let wasAdminUser: Bool = GroupMember
.filter(GroupMember.Columns.groupId == threadId)
.filter(GroupMember.Columns.profileId == currentUserPublicKey)
.filter(GroupMember.Columns.role == GroupMember.Role.admin)
.isNotEmpty(db)
if wasAdminUser {
try GroupMember
.filter(GroupMember.Columns.groupId == threadId)
.deleteAll(db)
}
else {
try GroupMember
.filter(GroupMember.Columns.groupId == threadId)
.filter(GroupMember.Columns.profileId == currentUserPublicKey)
.deleteAll(db)
}
// Clear out the group info as needed
try ClosedGroup.removeKeysAndUnsubscribe(
db,
threadId: threadId,
removeGroupData: details.deleteThread,
calledFromConfigHandling: false
)
}
success(job, false)
}
)
}

@ -2,7 +2,7 @@
import Foundation
public enum MessageSenderError: LocalizedError {
public enum MessageSenderError: LocalizedError, Equatable {
case invalidMessage
case protoConversionFailed
case noUserX25519KeyPair
@ -44,4 +44,26 @@ public enum MessageSenderError: LocalizedError {
case .other(let error): return error.localizedDescription
}
}
public static func == (lhs: MessageSenderError, rhs: MessageSenderError) -> Bool {
switch (lhs, rhs) {
case (.invalidMessage, .invalidMessage): return true
case (.protoConversionFailed, .protoConversionFailed): return true
case (.noUserX25519KeyPair, .noUserX25519KeyPair): return true
case (.noUserED25519KeyPair, .noUserED25519KeyPair): return true
case (.signingFailed, .signingFailed): return true
case (.encryptionFailed, .encryptionFailed): return true
case (.noUsername, .noUsername): return true
case (.attachmentsNotUploaded, .attachmentsNotUploaded): return true
case (.noThread, .noThread): return true
case (.noKeyPair, .noKeyPair): return true
case (.invalidClosedGroupUpdate, .invalidClosedGroupUpdate): return true
case (.other(let lhsError), .other(let rhsError)):
// Not ideal but the best we can do
return (lhsError.localizedDescription == rhsError.localizedDescription)
default: return false
}
}
}

Loading…
Cancel
Save