Cleanup proxy errors

- proxy errors have been getting repetitive and not particularly useful
- differentiate between sdk and client errors and keep what provides value
- add error logs everywhere a failure occurs
This commit is contained in:
Stefan Ceriu
2024-04-04 10:17:55 +03:00
committed by Stefan Ceriu
parent 3418d24557
commit c85c1593ee
16 changed files with 189 additions and 211 deletions
+17 -13
View File
@@ -24,6 +24,10 @@ struct ClientProxyMockConfiguration {
var roomDirectorySearchProxy: RoomDirectorySearchProxyProtocol? var roomDirectorySearchProxy: RoomDirectorySearchProxyProtocol?
} }
enum ClientProxyMockError: Error {
case generic
}
extension ClientProxyMock { extension ClientProxyMock {
convenience init(_ configuration: ClientProxyMockConfiguration) { convenience init(_ configuration: ClientProxyMockConfiguration) {
self.init() self.init()
@@ -53,25 +57,25 @@ extension ClientProxyMock {
isOnlyDeviceLeftReturnValue = .success(false) isOnlyDeviceLeftReturnValue = .success(false)
accountURLActionReturnValue = "https://matrix.org/account" accountURLActionReturnValue = "https://matrix.org/account"
directRoomForUserIDReturnValue = .failure(.failedRetrievingDirectRoom) directRoomForUserIDReturnValue = .failure(.sdkError(ClientProxyMockError.generic))
createDirectRoomWithExpectedRoomNameReturnValue = .failure(.failedCreatingRoom) createDirectRoomWithExpectedRoomNameReturnValue = .failure(.sdkError(ClientProxyMockError.generic))
createRoomNameTopicIsRoomPrivateUserIDsAvatarURLReturnValue = .failure(.failedCreatingRoom) createRoomNameTopicIsRoomPrivateUserIDsAvatarURLReturnValue = .failure(.sdkError(ClientProxyMockError.generic))
uploadMediaReturnValue = .failure(.failedUploadingMedia(.unknown)) uploadMediaReturnValue = .failure(.sdkError(ClientProxyMockError.generic))
loadUserDisplayNameReturnValue = .failure(.failedRetrievingUserDisplayName) loadUserDisplayNameReturnValue = .failure(.sdkError(ClientProxyMockError.generic))
setUserDisplayNameReturnValue = .failure(.failedSettingUserDisplayName) setUserDisplayNameReturnValue = .failure(.sdkError(ClientProxyMockError.generic))
loadUserAvatarURLReturnValue = .failure(.failedRetrievingUserAvatarURL) loadUserAvatarURLReturnValue = .failure(.sdkError(ClientProxyMockError.generic))
setUserAvatarMediaReturnValue = .failure(.failedSettingUserAvatar) setUserAvatarMediaReturnValue = .failure(.sdkError(ClientProxyMockError.generic))
removeUserAvatarReturnValue = .failure(.failedSettingUserAvatar) removeUserAvatarReturnValue = .failure(.sdkError(ClientProxyMockError.generic))
logoutReturnValue = nil logoutReturnValue = nil
searchUsersSearchTermLimitReturnValue = .success(.init(results: [], limited: false)) searchUsersSearchTermLimitReturnValue = .success(.init(results: [], limited: false))
profileForReturnValue = .success(.init(userID: "@a:b.com", displayName: "Some user")) profileForReturnValue = .success(.init(userID: "@a:b.com", displayName: "Some user"))
sessionVerificationControllerProxyReturnValue = .failure(.failedRetrievingSessionVerificationController) sessionVerificationControllerProxyReturnValue = .failure(.sdkError(ClientProxyMockError.generic))
ignoreUserReturnValue = .success(()) ignoreUserReturnValue = .success(())
unignoreUserReturnValue = .success(()) unignoreUserReturnValue = .success(())
loadMediaContentForSourceThrowableError = ClientProxyError.failedLoadingMedia loadMediaContentForSourceThrowableError = ClientProxyError.sdkError(ClientProxyMockError.generic)
loadMediaThumbnailForSourceWidthHeightThrowableError = ClientProxyError.failedLoadingMedia loadMediaThumbnailForSourceWidthHeightThrowableError = ClientProxyError.sdkError(ClientProxyMockError.generic)
loadMediaFileForSourceBodyThrowableError = ClientProxyError.failedLoadingMedia loadMediaFileForSourceBodyThrowableError = ClientProxyError.sdkError(ClientProxyMockError.generic)
secureBackupController = { secureBackupController = {
let secureBackupController = SecureBackupControllerMock() let secureBackupController = SecureBackupControllerMock()
+6 -2
View File
@@ -49,6 +49,10 @@ struct RoomProxyMockConfiguration {
var canUserJoinCall = true var canUserJoinCall = true
} }
enum RoomProxyMockError: Error {
case generic
}
extension RoomProxyMock { extension RoomProxyMock {
@MainActor @MainActor
convenience init(with configuration: RoomProxyMockConfiguration) { convenience init(with configuration: RoomProxyMockConfiguration) {
@@ -83,7 +87,7 @@ extension RoomProxyMock {
setTopicClosure = { _ in .success(()) } setTopicClosure = { _ in .success(()) }
getMemberUserIDClosure = { [weak self] userID in getMemberUserIDClosure = { [weak self] userID in
guard let member = self?.membersPublisher.value.first(where: { $0.userID == userID }) else { guard let member = self?.membersPublisher.value.first(where: { $0.userID == userID }) else {
return .failure(.failedRetrievingMember) return .failure(.sdkError(RoomProxyMockError.generic))
} }
return .success(member) return .success(member)
} }
@@ -98,7 +102,7 @@ extension RoomProxyMock {
resetPowerLevelsReturnValue = .success(.mock) resetPowerLevelsReturnValue = .success(.mock)
suggestedRoleForClosure = { [weak self] userID in suggestedRoleForClosure = { [weak self] userID in
guard case .success(let member) = await self?.getMember(userID: userID) else { guard case .success(let member) = await self?.getMember(userID: userID) else {
return .failure(.failedCheckingPermission) return .failure(.sdkError(RoomProxyMockError.generic))
} }
return .success(member.role) return .success(member.role)
} }
@@ -110,33 +110,6 @@ class CreateRoomViewModel: CreateRoomViewModelType, CreateRoomViewModelProtocol
.store(in: &cancellables) .store(in: &cancellables)
} }
private func displayError(_ type: ClientProxyError) {
switch type {
case .failedCreatingRoom:
state.bindings.alertInfo = AlertInfo(id: .failedCreatingRoom,
title: L10n.commonError,
message: L10n.screenStartChatErrorStartingChat)
case .failedSearchingUsers:
state.bindings.alertInfo = AlertInfo(id: .unknown)
case .failedUploadingMedia(let matrixError):
switch matrixError {
case .fileTooLarge:
// waiting for proper copy
state.bindings.alertInfo = AlertInfo(id: .fileTooLarge)
default:
state.bindings.alertInfo = AlertInfo(id: .failedUploadingMedia)
}
case .mediaFileError:
state.bindings.alertInfo = AlertInfo(id: .mediaFileError)
default:
break
}
}
private var clientProxy: ClientProxyProtocol {
userSession.clientProxy
}
private func createRoom() async { private func createRoom() async {
defer { defer {
hideLoadingIndicator() hideLoadingIndicator()
@@ -145,27 +118,42 @@ class CreateRoomViewModel: CreateRoomViewModelType, CreateRoomViewModelProtocol
let avatarURL: URL? let avatarURL: URL?
if let media = createRoomParameters.avatarImageMedia { if let media = createRoomParameters.avatarImageMedia {
switch await clientProxy.uploadMedia(media) { switch await userSession.clientProxy.uploadMedia(media) {
case .success(let url): case .success(let url):
avatarURL = URL(string: url) avatarURL = URL(string: url)
case .failure(let error): case .failure(let error):
displayError(error) switch error {
case .failedUploadingMedia(_, let errorCode):
switch errorCode {
case .fileTooLarge:
state.bindings.alertInfo = AlertInfo(id: .fileTooLarge)
default:
state.bindings.alertInfo = AlertInfo(id: .failedUploadingMedia)
}
case .invalidMedia:
state.bindings.alertInfo = AlertInfo(id: .mediaFileError)
default:
state.bindings.alertInfo = AlertInfo(id: .unknown)
}
return return
} }
} else { } else {
avatarURL = nil avatarURL = nil
} }
switch await clientProxy.createRoom(name: createRoomParameters.name, switch await userSession.clientProxy.createRoom(name: createRoomParameters.name,
topic: createRoomParameters.topic, topic: createRoomParameters.topic,
isRoomPrivate: createRoomParameters.isRoomPrivate, isRoomPrivate: createRoomParameters.isRoomPrivate,
userIDs: state.selectedUsers.map(\.userID), userIDs: state.selectedUsers.map(\.userID),
avatarURL: avatarURL) { avatarURL: avatarURL) {
case .success(let roomId): case .success(let roomId):
analytics.trackCreatedRoom(isDM: false) analytics.trackCreatedRoom(isDM: false)
actionsSubject.send(.openRoom(withIdentifier: roomId)) actionsSubject.send(.openRoom(withIdentifier: roomId))
case .failure(let failure): case .failure:
displayError(failure) state.bindings.alertInfo = AlertInfo(id: .failedCreatingRoom,
title: L10n.commonError,
message: L10n.screenStartChatErrorStartingChat)
} }
} }
@@ -119,7 +119,7 @@ class InvitesScreenViewModel: InvitesScreenViewModelType, InvitesScreenViewModel
userIndicatorController.submitIndicator(UserIndicator(id: roomID, type: .modal, title: L10n.commonLoading, persistent: true)) userIndicatorController.submitIndicator(UserIndicator(id: roomID, type: .modal, title: L10n.commonLoading, persistent: true))
guard let roomProxy = await clientProxy.roomForIdentifier(roomID) else { guard let roomProxy = await clientProxy.roomForIdentifier(roomID) else {
displayError(.failedAcceptingInvite) displayError()
return return
} }
@@ -127,8 +127,8 @@ class InvitesScreenViewModel: InvitesScreenViewModelType, InvitesScreenViewModel
case .success: case .success:
actionsSubject.send(.openRoom(withIdentifier: roomID)) actionsSubject.send(.openRoom(withIdentifier: roomID))
analytics.trackJoinedRoom(isDM: roomProxy.isDirect, isSpace: roomProxy.isSpace, activeMemberCount: UInt(roomProxy.activeMembersCount)) analytics.trackJoinedRoom(isDM: roomProxy.isDirect, isSpace: roomProxy.isSpace, activeMemberCount: UInt(roomProxy.activeMembersCount))
case .failure(let error): case .failure:
displayError(error) displayError()
} }
} }
} }
@@ -143,20 +143,19 @@ class InvitesScreenViewModel: InvitesScreenViewModelType, InvitesScreenViewModel
userIndicatorController.submitIndicator(UserIndicator(id: roomID, type: .modal, title: L10n.commonLoading, persistent: true)) userIndicatorController.submitIndicator(UserIndicator(id: roomID, type: .modal, title: L10n.commonLoading, persistent: true))
guard let roomProxy = await clientProxy.roomForIdentifier(roomID) else { guard let roomProxy = await clientProxy.roomForIdentifier(roomID) else {
displayError(.failedRejectingInvite) displayError()
return return
} }
let result = await roomProxy.rejectInvitation() let result = await roomProxy.rejectInvitation()
if case .failure(let error) = result { if case .failure = result {
displayError(error) displayError()
} }
} }
} }
private func displayError(_ error: RoomProxyError) { private func displayError() {
MXLog.error("Failed to accept/decline invite: \(error)")
state.bindings.alertInfo = .init(id: true, state.bindings.alertInfo = .init(id: true,
title: L10n.commonError, title: L10n.commonError,
message: L10n.errorUnknown) message: L10n.errorUnknown)
@@ -48,9 +48,9 @@ class RoomDetailsEditScreenViewModel: RoomDetailsEditScreenViewModelType, RoomDe
Task { Task {
// Can't use async let because the mocks aren't thread safe when calling the same method 🤦‍♂️ // Can't use async let because the mocks aren't thread safe when calling the same method 🤦‍♂️
state.canEditAvatar = await roomProxy.canUser(userID: roomProxy.ownUserID, sendStateEvent: .roomAvatar) == .success(true) state.canEditAvatar = await (try? roomProxy.canUser(userID: roomProxy.ownUserID, sendStateEvent: .roomAvatar).get()) == .some(true)
state.canEditName = await roomProxy.canUser(userID: roomProxy.ownUserID, sendStateEvent: .roomName) == .success(true) state.canEditName = await (try? roomProxy.canUser(userID: roomProxy.ownUserID, sendStateEvent: .roomName).get()) == .some(true)
state.canEditTopic = await roomProxy.canUser(userID: roomProxy.ownUserID, sendStateEvent: .roomTopic) == .success(true) state.canEditTopic = await (try? roomProxy.canUser(userID: roomProxy.ownUserID, sendStateEvent: .roomTopic).get()) == .some(true)
} }
} }
@@ -178,15 +178,15 @@ class RoomDetailsScreenViewModel: RoomDetailsScreenViewModelType, RoomDetailsScr
} }
private func updatePowerLevelPermissions() async { private func updatePowerLevelPermissions() async {
async let canInviteUsers = roomProxy.canUserInvite(userID: roomProxy.ownUserID) == .success(true) state.canEditRoomName = await (try? roomProxy.canUser(userID: roomProxy.ownUserID, sendStateEvent: .roomName).get()) == true
// Can't use async let because the mocks aren't thread safe when calling the same method 🤦‍♂️ state.canEditRoomTopic = await (try? roomProxy.canUser(userID: roomProxy.ownUserID, sendStateEvent: .roomTopic).get()) == true
state.canEditRoomName = await roomProxy.canUser(userID: roomProxy.ownUserID, sendStateEvent: .roomName) == .success(true) state.canEditRoomAvatar = await (try? roomProxy.canUser(userID: roomProxy.ownUserID, sendStateEvent: .roomAvatar).get()) == true
state.canEditRoomTopic = await roomProxy.canUser(userID: roomProxy.ownUserID, sendStateEvent: .roomTopic) == .success(true)
state.canEditRoomAvatar = await roomProxy.canUser(userID: roomProxy.ownUserID, sendStateEvent: .roomAvatar) == .success(true)
if appSettings.roomModerationEnabled { if appSettings.roomModerationEnabled {
state.canEditRolesOrPermissions = await roomProxy.suggestedRole(for: roomProxy.ownUserID) == .success(.administrator) state.canEditRolesOrPermissions = await (try? roomProxy.suggestedRole(for: roomProxy.ownUserID).get()) == .administrator
} }
state.canInviteUsers = await canInviteUsers
state.canInviteUsers = await (try? roomProxy.canUserInvite(userID: roomProxy.ownUserID).get()) == true
} }
private func setupNotificationSettingsSubscription() { private func setupNotificationSettingsSubscription() {
@@ -110,12 +110,9 @@ class RoomMembersListScreenViewModel: RoomMembersListScreenViewModelType, RoomMe
bannedMembers: roomMembersDetails.bannedMembers, bannedMembers: roomMembersDetails.bannedMembers,
bindings: state.bindings) bindings: state.bindings)
async let canInviteUsers = roomProxy.canUserInvite(userID: roomProxy.ownUserID) self.state.canInviteUsers = await (try? roomProxy.canUserInvite(userID: roomProxy.ownUserID).get()) == true
async let canKickUsers = roomProxy.canUserKick(userID: roomProxy.ownUserID) self.state.canKickUsers = await (try? roomProxy.canUserKick(userID: roomProxy.ownUserID).get()) == true
async let canBanUsers = roomProxy.canUserBan(userID: roomProxy.ownUserID) self.state.canBanUsers = await (try? roomProxy.canUserBan(userID: roomProxy.ownUserID).get()) == true
self.state.canInviteUsers = await canInviteUsers == .success(true)
self.state.canKickUsers = await canKickUsers == .success(true)
self.state.canBanUsers = await canBanUsers == .success(true)
hideLoader() hideLoader()
} }
@@ -56,16 +56,16 @@ class StartChatScreenViewModel: StartChatScreenViewModelType, StartChatScreenVie
case .selectUser(let user): case .selectUser(let user):
showLoadingIndicator() showLoadingIndicator()
Task { Task {
let currentDirectRoom = await clientProxy.directRoomForUserID(user.userID) let currentDirectRoom = await userSession.clientProxy.directRoomForUserID(user.userID)
switch currentDirectRoom { switch currentDirectRoom {
case .success(.some(let roomId)): case .success(.some(let roomId)):
self.hideLoadingIndicator() self.hideLoadingIndicator()
self.actionsSubject.send(.openRoom(withIdentifier: roomId)) self.actionsSubject.send(.openRoom(withIdentifier: roomId))
case .success(nil): case .success:
await self.createDirectRoom(with: user) await self.createDirectRoom(with: user)
case .failure(let failure): case .failure:
self.hideLoadingIndicator() self.hideLoadingIndicator()
self.displayError(failure) self.displayError()
} }
} }
} }
@@ -73,19 +73,6 @@ class StartChatScreenViewModel: StartChatScreenViewModelType, StartChatScreenVie
// MARK: - Private // MARK: - Private
private func displayError(_ type: ClientProxyError) {
switch type {
case .failedCreatingRoom, .failedRetrievingDirectRoom:
state.bindings.alertInfo = AlertInfo(id: .failedCreatingRoom,
title: L10n.commonError,
message: L10n.screenStartChatErrorStartingChat)
case .failedSearchingUsers:
state.bindings.alertInfo = AlertInfo(id: .unknown)
default:
break
}
}
private func setupBindings() { private func setupBindings() {
context.$viewState context.$viewState
.map(\.bindings.searchQuery) .map(\.bindings.searchQuery)
@@ -101,12 +88,12 @@ class StartChatScreenViewModel: StartChatScreenViewModelType, StartChatScreenVie
private var fetchUsersTask: Task<Void, Never>? private var fetchUsersTask: Task<Void, Never>?
private func fetchUsers() { private func fetchUsers() {
guard searchQuery.count >= 3 else { guard context.searchQuery.count >= 3 else {
state.usersSection = .init(type: .suggestions, users: []) state.usersSection = .init(type: .suggestions, users: [])
return return
} }
fetchUsersTask = Task { fetchUsersTask = Task {
let result = await userDiscoveryService.searchProfiles(with: searchQuery) let result = await userDiscoveryService.searchProfiles(with: context.searchQuery)
guard !Task.isCancelled else { return } guard !Task.isCancelled else { return }
handleResult(for: .searchResult, result: result) handleResult(for: .searchResult, result: result)
} }
@@ -117,7 +104,7 @@ class StartChatScreenViewModel: StartChatScreenViewModelType, StartChatScreenVie
case .success(let users): case .success(let users):
state.usersSection = .init(type: sectionType, users: users) state.usersSection = .init(type: sectionType, users: users)
case .failure: case .failure:
break state.bindings.alertInfo = AlertInfo(id: .unknown)
} }
} }
@@ -126,23 +113,21 @@ class StartChatScreenViewModel: StartChatScreenViewModelType, StartChatScreenVie
hideLoadingIndicator() hideLoadingIndicator()
} }
showLoadingIndicator() showLoadingIndicator()
switch await clientProxy.createDirectRoom(with: user.userID, expectedRoomName: user.displayName) { switch await userSession.clientProxy.createDirectRoom(with: user.userID, expectedRoomName: user.displayName) {
case .success(let roomId): case .success(let roomId):
analytics.trackCreatedRoom(isDM: true) analytics.trackCreatedRoom(isDM: true)
actionsSubject.send(.openRoom(withIdentifier: roomId)) actionsSubject.send(.openRoom(withIdentifier: roomId))
case .failure(let failure): case .failure:
displayError(failure) displayError()
} }
} }
private var clientProxy: ClientProxyProtocol { private func displayError() {
userSession.clientProxy state.bindings.alertInfo = AlertInfo(id: .failedCreatingRoom,
title: L10n.commonError,
message: L10n.screenStartChatErrorStartingChat)
} }
private var searchQuery: String {
context.searchQuery
}
// MARK: Loading indicator // MARK: Loading indicator
private static let loadingIndicatorIdentifier = "\(StartChatScreenViewModel.self)-Loading" private static let loadingIndicatorIdentifier = "\(StartChatScreenViewModel.self)-Loading"
@@ -216,7 +216,7 @@ class ClientProxy: ClientProxyProtocol {
return .success(result) return .success(result)
} catch { } catch {
MXLog.error("Failed checking isLastDevice with error: \(error)") MXLog.error("Failed checking isLastDevice with error: \(error)")
return .failure(.failedCheckingIsLastDevice(error)) return .failure(.sdkError(error))
} }
} }
@@ -293,7 +293,8 @@ class ClientProxy: ClientProxyProtocol {
let roomID = try self.client.getDmRoom(userId: userID)?.id() let roomID = try self.client.getDmRoom(userId: userID)?.id()
return .success(roomID) return .success(roomID)
} catch { } catch {
return .failure(.failedRetrievingDirectRoom) MXLog.error("Failed retrieving direct room for userID: \(userID) with error: \(error)")
return .failure(.sdkError(error))
} }
} }
} }
@@ -313,7 +314,8 @@ class ClientProxy: ClientProxyProtocol {
let result = try self.client.createRoom(request: parameters) let result = try self.client.createRoom(request: parameters)
return .success(result) return .success(result)
} catch { } catch {
return .failure(.failedCreatingRoom) MXLog.error("Failed creating direct room for userID: \(userID) with error: \(error)")
return .failure(.sdkError(error))
} }
} }
@@ -335,7 +337,8 @@ class ClientProxy: ClientProxyProtocol {
let roomID = try self.client.createRoom(request: parameters) let roomID = try self.client.createRoom(request: parameters)
return .success(roomID) return .success(roomID)
} catch { } catch {
return .failure(.failedCreatingRoom) MXLog.error("Failed creating room with error: \(error)")
return .failure(.sdkError(error))
} }
} }
@@ -351,20 +354,27 @@ class ClientProxy: ClientProxyProtocol {
return .success(()) return .success(())
} catch { } catch {
return .failure(.failedJoiningRoom) MXLog.error("Failed joining roomID: \(roomID) with error: \(error)")
return .failure(.sdkError(error))
} }
} }
func uploadMedia(_ media: MediaInfo) async -> Result<String, ClientProxyError> { func uploadMedia(_ media: MediaInfo) async -> Result<String, ClientProxyError> {
guard let mimeType = media.mimeType else { return .failure(ClientProxyError.mediaFileError) } guard let mimeType = media.mimeType else {
MXLog.error("Failed uploading media, invalid mime type: \(media)")
return .failure(ClientProxyError.invalidMedia)
}
do { do {
let data = try Data(contentsOf: media.url) let data = try Data(contentsOf: media.url)
let matrixUrl = try await client.uploadMedia(mimeType: mimeType, data: data, progressWatcher: nil) let matrixUrl = try await client.uploadMedia(mimeType: mimeType, data: data, progressWatcher: nil)
return .success(matrixUrl) return .success(matrixUrl)
} catch let error as ClientError { } catch let error as ClientError {
return .failure(ClientProxyError.failedUploadingMedia(error.code)) MXLog.error("Failed uploading media with error: \(error)")
return .failure(ClientProxyError.failedUploadingMedia(error, error.code))
} catch { } catch {
return .failure(ClientProxyError.mediaFileError) MXLog.error("Failed uploading media with error: \(error)")
return .failure(ClientProxyError.sdkError(error))
} }
} }
@@ -435,7 +445,8 @@ class ClientProxy: ClientProxyProtocol {
self.userDisplayNameSubject.send(displayName) self.userDisplayNameSubject.send(displayName)
return .success(()) return .success(())
} catch { } catch {
return .failure(.failedRetrievingUserDisplayName) MXLog.error("Failed loading user display name with error: \(error)")
return .failure(.sdkError(error))
} }
} }
} }
@@ -449,7 +460,8 @@ class ClientProxy: ClientProxyProtocol {
} }
return .success(()) return .success(())
} catch { } catch {
return .failure(.failedSettingUserDisplayName) MXLog.error("Failed setting user display name with error: \(error)")
return .failure(.sdkError(error))
} }
} }
} }
@@ -462,7 +474,8 @@ class ClientProxy: ClientProxyProtocol {
self.userAvatarURLSubject.send(urlString.flatMap(URL.init)) self.userAvatarURLSubject.send(urlString.flatMap(URL.init))
return .success(()) return .success(())
} catch { } catch {
return .failure(.failedRetrievingUserAvatarURL) MXLog.error("Failed loading user avatar URL with error: \(error)")
return .failure(.sdkError(error))
} }
} }
} }
@@ -470,7 +483,8 @@ class ClientProxy: ClientProxyProtocol {
func setUserAvatar(media: MediaInfo) async -> Result<Void, ClientProxyError> { func setUserAvatar(media: MediaInfo) async -> Result<Void, ClientProxyError> {
await Task.dispatch(on: .global()) { await Task.dispatch(on: .global()) {
guard case let .image(imageURL, _, _) = media, let mimeType = media.mimeType else { guard case let .image(imageURL, _, _) = media, let mimeType = media.mimeType else {
return .failure(.failedSettingUserAvatar) MXLog.error("Failed uploading, invalid media: \(media)")
return .failure(.invalidMedia)
} }
do { do {
@@ -481,7 +495,8 @@ class ClientProxy: ClientProxyProtocol {
} }
return .success(()) return .success(())
} catch { } catch {
return .failure(.failedSettingUserAvatar) MXLog.error("Failed setting user avatar with error: \(error)")
return .failure(.sdkError(error))
} }
} }
} }
@@ -495,7 +510,8 @@ class ClientProxy: ClientProxyProtocol {
} }
return .success(()) return .success(())
} catch { } catch {
return .failure(.failedSettingUserAvatar) MXLog.error("Failed removing user avatar with error: \(error)")
return .failure(.sdkError(error))
} }
} }
} }
@@ -506,7 +522,8 @@ class ClientProxy: ClientProxyProtocol {
let sessionVerificationController = try self.client.getSessionVerificationController() let sessionVerificationController = try self.client.getSessionVerificationController()
return .success(SessionVerificationControllerProxy(sessionVerificationController: sessionVerificationController)) return .success(SessionVerificationControllerProxy(sessionVerificationController: sessionVerificationController))
} catch { } catch {
return .failure(.failedRetrievingSessionVerificationController) MXLog.error("Failed retrieving session verification controller proxy with error: \(error)")
return .failure(.sdkError(error))
} }
} }
} }
@@ -536,7 +553,8 @@ class ClientProxy: ClientProxyProtocol {
do { do {
return try .success(.init(sdkResults: self.client.searchUsers(searchTerm: searchTerm, limit: UInt64(limit)))) return try .success(.init(sdkResults: self.client.searchUsers(searchTerm: searchTerm, limit: UInt64(limit))))
} catch { } catch {
return .failure(.failedSearchingUsers) MXLog.error("Failed searching users with error: \(error)")
return .failure(.sdkError(error))
} }
} }
} }
@@ -546,7 +564,8 @@ class ClientProxy: ClientProxyProtocol {
do { do {
return try .success(.init(sdkUserProfile: self.client.getProfile(userId: userID))) return try .success(.init(sdkUserProfile: self.client.getProfile(userId: userID)))
} catch { } catch {
return .failure(.failedGettingUserProfile) MXLog.error("Failed retrieving profile for userID: \(userID) with error: \(error)")
return .failure(.sdkError(error))
} }
} }
} }
@@ -563,7 +582,7 @@ class ClientProxy: ClientProxyProtocol {
return .success(()) return .success(())
} catch { } catch {
MXLog.error("Failed ignoring user with error: \(error)") MXLog.error("Failed ignoring user with error: \(error)")
return .failure(.failedIgnoringUser) return .failure(.sdkError(error))
} }
} }
@@ -573,7 +592,7 @@ class ClientProxy: ClientProxyProtocol {
return .success(()) return .success(())
} catch { } catch {
MXLog.error("Failed unignoring user with error: \(error)") MXLog.error("Failed unignoring user with error: \(error)")
return .failure(.failedUnignoringUser) return .failure(.sdkError(error))
} }
} }
@@ -38,22 +38,9 @@ enum ClientProxyLoadingState {
} }
enum ClientProxyError: Error { enum ClientProxyError: Error {
case failedCreatingRoom case sdkError(Error)
case failedRetrievingDirectRoom case invalidMedia
case failedRetrievingUserDisplayName case failedUploadingMedia(Error, MatrixErrorCode)
case failedRetrievingUserAvatarURL
case failedSettingUserDisplayName
case failedRetrievingSessionVerificationController
case failedLoadingMedia
case mediaFileError
case failedUploadingMedia(MatrixErrorCode)
case failedSearchingUsers
case failedGettingUserProfile
case failedSettingUserAvatar
case failedCheckingIsLastDevice(Error?)
case failedIgnoringUser
case failedUnignoringUser
case failedJoiningRoom
} }
enum SlidingSyncConstants { enum SlidingSyncConstants {
+51 -41
View File
@@ -168,7 +168,8 @@ class RoomProxy: RoomProxyProtocol {
try self.room.redact(eventId: eventID, reason: nil) try self.room.redact(eventId: eventID, reason: nil)
return .success(()) return .success(())
} catch { } catch {
return .failure(.failedRedactingEvent) MXLog.error("Failed redacting eventID: \(eventID) with error: \(error)")
return .failure(.sdkError(error))
} }
} }
} }
@@ -184,7 +185,8 @@ class RoomProxy: RoomProxyProtocol {
try self.room.reportContent(eventId: eventID, score: nil, reason: reason) try self.room.reportContent(eventId: eventID, score: nil, reason: reason)
return .success(()) return .success(())
} catch { } catch {
return .failure(.failedReportingContent) MXLog.error("Failed reporting eventID: \(eventID) with error: \(error)")
return .failure(.sdkError(error))
} }
} }
} }
@@ -198,7 +200,7 @@ class RoomProxy: RoomProxyProtocol {
membersSubject.value = members.map(RoomMemberProxy.init) membersSubject.value = members.map(RoomMemberProxy.init)
} }
} catch { } catch {
MXLog.error("[RoomProxy] Failed to update members using no sync API: \(error)") MXLog.error("[RoomProxy] Failed updating members using no sync API: \(error)")
} }
do { do {
@@ -208,7 +210,7 @@ class RoomProxy: RoomProxyProtocol {
membersSubject.value = members.map(RoomMemberProxy.init) membersSubject.value = members.map(RoomMemberProxy.init)
} }
} catch { } catch {
MXLog.error("[RoomProxy] Failed to update members using sync API: \(error)") MXLog.error("[RoomProxy] Failed updating members using sync API: \(error)")
} }
} }
@@ -226,7 +228,8 @@ class RoomProxy: RoomProxyProtocol {
let member = try await room.member(userId: userID) let member = try await room.member(userId: userID)
return .success(RoomMemberProxy(member: member)) return .success(RoomMemberProxy(member: member))
} catch { } catch {
return .failure(.failedRetrievingMember) MXLog.error("Failed retrieving member \(userID) with error: \(error)")
return .failure(.sdkError(error))
} }
} }
@@ -241,8 +244,8 @@ class RoomProxy: RoomProxyProtocol {
try self.room.leave() try self.room.leave()
return .success(()) return .success(())
} catch { } catch {
MXLog.error("Failed to leave the room: \(error)") MXLog.error("Failed leaving room with error: \(error)")
return .failure(.failedLeavingRoom) return .failure(.sdkError(error))
} }
} }
} }
@@ -252,7 +255,8 @@ class RoomProxy: RoomProxyProtocol {
do { do {
return try .success(self.room.leave()) return try .success(self.room.leave())
} catch { } catch {
return .failure(.failedRejectingInvite) MXLog.error("Failed rejecting invitiation with error: \(error)")
return .failure(.sdkError(error))
} }
} }
} }
@@ -263,7 +267,8 @@ class RoomProxy: RoomProxyProtocol {
try self.room.join() try self.room.join()
return .success(()) return .success(())
} catch { } catch {
return .failure(.failedAcceptingInvite) MXLog.error("Failed accepting invitation with error: \(error)")
return .failure(.sdkError(error))
} }
} }
} }
@@ -275,7 +280,7 @@ class RoomProxy: RoomProxyProtocol {
return try .success(self.room.inviteUserById(userId: userID)) return try .success(self.room.inviteUserById(userId: userID))
} catch { } catch {
MXLog.error("Failed inviting user \(userID) with error: \(error)") MXLog.error("Failed inviting user \(userID) with error: \(error)")
return .failure(.failedInvitingUser) return .failure(.sdkError(error))
} }
} }
} }
@@ -285,7 +290,8 @@ class RoomProxy: RoomProxyProtocol {
do { do {
return try .success(self.room.setName(name: name)) return try .success(self.room.setName(name: name))
} catch { } catch {
return .failure(.failedSettingRoomName) MXLog.error("Failed setting name with error: \(error)")
return .failure(.sdkError(error))
} }
} }
} }
@@ -295,7 +301,8 @@ class RoomProxy: RoomProxyProtocol {
do { do {
return try .success(self.room.setTopic(topic: topic)) return try .success(self.room.setTopic(topic: topic))
} catch { } catch {
return .failure(.failedSettingRoomTopic) MXLog.error("Failed setting topic with error: \(error)")
return .failure(.sdkError(error))
} }
} }
} }
@@ -305,7 +312,8 @@ class RoomProxy: RoomProxyProtocol {
do { do {
return try .success(self.room.removeAvatar()) return try .success(self.room.removeAvatar())
} catch { } catch {
return .failure(.failedRemovingAvatar) MXLog.error("Failed removing avatar with error: \(error)")
return .failure(.sdkError(error))
} }
} }
} }
@@ -313,14 +321,16 @@ class RoomProxy: RoomProxyProtocol {
func uploadAvatar(media: MediaInfo) async -> Result<Void, RoomProxyError> { func uploadAvatar(media: MediaInfo) async -> Result<Void, RoomProxyError> {
await Task.dispatch(on: .global()) { await Task.dispatch(on: .global()) {
guard case let .image(imageURL, _, _) = media, let mimeType = media.mimeType else { guard case let .image(imageURL, _, _) = media, let mimeType = media.mimeType else {
return .failure(.failedUploadingAvatar) MXLog.error("Failed uploading avatar, invalid media: \(media)")
return .failure(.invalidMedia)
} }
do { do {
let data = try Data(contentsOf: imageURL) let data = try Data(contentsOf: imageURL)
return try .success(self.room.uploadAvatar(mimeType: mimeType, data: data, mediaInfo: nil)) return try .success(self.room.uploadAvatar(mimeType: mimeType, data: data, mediaInfo: nil))
} catch { } catch {
return .failure(.failedUploadingAvatar) MXLog.error("Failed uploading avatar with error: \(error)")
return .failure(.sdkError(error))
} }
} }
} }
@@ -331,7 +341,7 @@ class RoomProxy: RoomProxyProtocol {
return .success(()) return .success(())
} catch { } catch {
MXLog.error("Failed marking room \(id) as read with error: \(error)") MXLog.error("Failed marking room \(id) as read with error: \(error)")
return .failure(.failedMarkingAsRead) return .failure(.sdkError(error))
} }
} }
@@ -343,7 +353,7 @@ class RoomProxy: RoomProxyProtocol {
return .success(()) return .success(())
} catch { } catch {
MXLog.error("Failed sending typing notice with error: \(error)") MXLog.error("Failed sending typing notice with error: \(error)")
return .failure(.failedSendingTypingNotice) return .failure(.sdkError(error))
} }
} }
@@ -357,7 +367,7 @@ class RoomProxy: RoomProxyProtocol {
return .success(()) return .success(())
} catch { } catch {
MXLog.error("Failed marking room \(id) as unread: \(isUnread) with error: \(error)") MXLog.error("Failed marking room \(id) as unread: \(isUnread) with error: \(error)")
return .failure(.failedFlaggingAsUnread) return .failure(.sdkError(error))
} }
} }
@@ -367,7 +377,7 @@ class RoomProxy: RoomProxyProtocol {
return .success(()) return .success(())
} catch { } catch {
MXLog.error("Failed flagging room \(id) as favourite with error: \(error)") MXLog.error("Failed flagging room \(id) as favourite with error: \(error)")
return .failure(.failedFlaggingAsFavourite) return .failure(.sdkError(error))
} }
} }
@@ -378,7 +388,7 @@ class RoomProxy: RoomProxyProtocol {
return try await .success(room.getPowerLevels()) return try await .success(room.getPowerLevels())
} catch { } catch {
MXLog.error("Failed building the current power level settings: \(error)") MXLog.error("Failed building the current power level settings: \(error)")
return .failure(.failedCheckingPermission) return .failure(.sdkError(error))
} }
} }
@@ -387,7 +397,7 @@ class RoomProxy: RoomProxyProtocol {
return try await .success(room.applyPowerLevelChanges(changes: changes)) return try await .success(room.applyPowerLevelChanges(changes: changes))
} catch { } catch {
MXLog.error("Failed applying the power level changes: \(error)") MXLog.error("Failed applying the power level changes: \(error)")
return .failure(.failedSettingPermission) return .failure(.sdkError(error))
} }
} }
@@ -396,7 +406,7 @@ class RoomProxy: RoomProxyProtocol {
return try await .success(room.resetPowerLevels()) return try await .success(room.resetPowerLevels())
} catch { } catch {
MXLog.error("Failed resetting the power levels: \(error)") MXLog.error("Failed resetting the power levels: \(error)")
return .failure(.failedSettingPermission) return .failure(.sdkError(error))
} }
} }
@@ -405,7 +415,7 @@ class RoomProxy: RoomProxyProtocol {
return try await .success(room.suggestedRoleForUser(userId: userID)) return try await .success(room.suggestedRoleForUser(userId: userID))
} catch { } catch {
MXLog.error("Failed getting a user's role: \(error)") MXLog.error("Failed getting a user's role: \(error)")
return .failure(.failedCheckingPermission) return .failure(.sdkError(error))
} }
} }
@@ -415,7 +425,7 @@ class RoomProxy: RoomProxyProtocol {
return try await .success(room.updatePowerLevelsForUsers(updates: updates)) return try await .success(room.updatePowerLevelsForUsers(updates: updates))
} catch { } catch {
MXLog.error("Failed updating user power levels changes: \(error)") MXLog.error("Failed updating user power levels changes: \(error)")
return .failure(.failedSettingPermission) return .failure(.sdkError(error))
} }
} }
@@ -424,7 +434,7 @@ class RoomProxy: RoomProxyProtocol {
return try await .success(room.canUserSendState(userId: userID, stateEvent: event)) return try await .success(room.canUserSendState(userId: userID, stateEvent: event))
} catch { } catch {
MXLog.error("Failed checking if the user can send \(event) with error: \(error)") MXLog.error("Failed checking if the user can send \(event) with error: \(error)")
return .failure(.failedCheckingPermission) return .failure(.sdkError(error))
} }
} }
@@ -433,7 +443,7 @@ class RoomProxy: RoomProxyProtocol {
return try await .success(room.canUserInvite(userId: userID)) return try await .success(room.canUserInvite(userId: userID))
} catch { } catch {
MXLog.error("Failed checking if the user can invite with error: \(error)") MXLog.error("Failed checking if the user can invite with error: \(error)")
return .failure(.failedCheckingPermission) return .failure(.sdkError(error))
} }
} }
@@ -442,7 +452,7 @@ class RoomProxy: RoomProxyProtocol {
return try await .success(room.canUserRedactOther(userId: userID)) return try await .success(room.canUserRedactOther(userId: userID))
} catch { } catch {
MXLog.error("Failed checking if the user can redact others with error: \(error)") MXLog.error("Failed checking if the user can redact others with error: \(error)")
return .failure(.failedCheckingPermission) return .failure(.sdkError(error))
} }
} }
@@ -451,7 +461,7 @@ class RoomProxy: RoomProxyProtocol {
return try await .success(room.canUserRedactOwn(userId: userID)) return try await .success(room.canUserRedactOwn(userId: userID))
} catch { } catch {
MXLog.error("Failed checking if the user can redact self with error: \(error)") MXLog.error("Failed checking if the user can redact self with error: \(error)")
return .failure(.failedCheckingPermission) return .failure(.sdkError(error))
} }
} }
@@ -460,7 +470,7 @@ class RoomProxy: RoomProxyProtocol {
return try await .success(room.canUserKick(userId: userID)) return try await .success(room.canUserKick(userId: userID))
} catch { } catch {
MXLog.error("Failed checking if the user can kick with error: \(error)") MXLog.error("Failed checking if the user can kick with error: \(error)")
return .failure(.failedCheckingPermission) return .failure(.sdkError(error))
} }
} }
@@ -469,7 +479,7 @@ class RoomProxy: RoomProxyProtocol {
return try await .success(room.canUserBan(userId: userID)) return try await .success(room.canUserBan(userId: userID))
} catch { } catch {
MXLog.error("Failed checking if the user can ban with error: \(error)") MXLog.error("Failed checking if the user can ban with error: \(error)")
return .failure(.failedCheckingPermission) return .failure(.sdkError(error))
} }
} }
@@ -478,7 +488,7 @@ class RoomProxy: RoomProxyProtocol {
return try await .success(room.canUserTriggerRoomNotification(userId: userID)) return try await .success(room.canUserTriggerRoomNotification(userId: userID))
} catch { } catch {
MXLog.error("Failed checking if the user can trigger room notification with error: \(error)") MXLog.error("Failed checking if the user can trigger room notification with error: \(error)")
return .failure(.failedCheckingPermission) return .failure(.sdkError(error))
} }
} }
@@ -490,7 +500,7 @@ class RoomProxy: RoomProxyProtocol {
return .success(()) return .success(())
} catch { } catch {
MXLog.error("Failed kicking \(userID) with error: \(error)") MXLog.error("Failed kicking \(userID) with error: \(error)")
return .failure(.failedModeration) return .failure(.sdkError(error))
} }
} }
@@ -500,7 +510,7 @@ class RoomProxy: RoomProxyProtocol {
return .success(()) return .success(())
} catch { } catch {
MXLog.error("Failed banning \(userID) with error: \(error)") MXLog.error("Failed banning \(userID) with error: \(error)")
return .failure(.failedModeration) return .failure(.sdkError(error))
} }
} }
@@ -510,7 +520,7 @@ class RoomProxy: RoomProxyProtocol {
return .success(()) return .success(())
} catch { } catch {
MXLog.error("Failed unbanning \(userID) with error: \(error)") MXLog.error("Failed unbanning \(userID) with error: \(error)")
return .failure(.failedModeration) return .failure(.sdkError(error))
} }
} }
@@ -521,7 +531,7 @@ class RoomProxy: RoomProxyProtocol {
return try await .success(room.canUserSendState(userId: userID, stateEvent: .callMember)) return try await .success(room.canUserSendState(userId: userID, stateEvent: .callMember))
} catch { } catch {
MXLog.error("Failed checking if the user can trigger room notification with error: \(error)") MXLog.error("Failed checking if the user can trigger room notification with error: \(error)")
return .failure(.failedCheckingPermission) return .failure(.sdkError(error))
} }
} }
@@ -536,14 +546,14 @@ class RoomProxy: RoomProxyProtocol {
let urlString = try await room.matrixToPermalink() let urlString = try await room.matrixToPermalink()
guard let url = URL(string: urlString) else { guard let url = URL(string: urlString) else {
MXLog.error("Invalid permalink URL string: \(urlString)") MXLog.error("Failed creating permalink for roomID: \(id), invalid permalink URL string: \(urlString)")
return .failure(.generic("Invalid permalink URL string: \(urlString)")) return .failure(.invalidURL)
} }
return .success(url) return .success(url)
} catch { } catch {
MXLog.error("Failed creating permalink for roomID: \(id) with error: \(error)") MXLog.error("Failed creating permalink for roomID: \(id) with error: \(error)")
return .failure(.generic(error.localizedDescription)) return .failure(.sdkError(error))
} }
} }
@@ -552,14 +562,14 @@ class RoomProxy: RoomProxyProtocol {
let urlString = try await room.matrixToEventPermalink(eventId: eventID) let urlString = try await room.matrixToEventPermalink(eventId: eventID)
guard let url = URL(string: urlString) else { guard let url = URL(string: urlString) else {
MXLog.error("Invalid permalink URL string: \(urlString)") MXLog.error("Failed creating permalink for eventID: \(eventID), invalid permalink URL string: \(urlString)")
return .failure(.generic("Invalid permalink URL string: \(urlString)")) return .failure(.invalidURL)
} }
return .success(url) return .success(url)
} catch { } catch {
MXLog.error("Failed creating permalink for eventID: \(eventID) with error: \(error)") MXLog.error("Failed creating permalink for eventID: \(eventID) with error: \(error)")
return .failure(.generic(error.localizedDescription)) return .failure(.sdkError(error))
} }
} }
@@ -18,26 +18,11 @@ import Combine
import Foundation import Foundation
import MatrixRustSDK import MatrixRustSDK
enum RoomProxyError: Error, Equatable { enum RoomProxyError: Error {
case generic(String?) case sdkError(Error)
case failedRedactingEvent
case failedReportingContent case invalidURL
case failedRetrievingMember case invalidMedia
case failedLeavingRoom
case failedAcceptingInvite
case failedRejectingInvite
case failedInvitingUser
case failedSettingRoomName
case failedSettingRoomTopic
case failedRemovingAvatar
case failedUploadingAvatar
case failedCheckingPermission
case failedSettingPermission
case failedFlaggingAsUnread
case failedMarkingAsRead
case failedSendingTypingNotice
case failedFlaggingAsFavourite
case failedModeration
} }
enum RoomProxyAction { enum RoomProxyAction {
@@ -105,7 +105,7 @@ class HomeScreenViewModelTests: XCTestCase {
func testLeaveRoomError() async throws { func testLeaveRoomError() async throws {
let mockRoomId = "1" let mockRoomId = "1"
let room: RoomProxyMock = .init(with: .init(id: mockRoomId, name: "Some room")) let room: RoomProxyMock = .init(with: .init(id: mockRoomId, name: "Some room"))
room.leaveRoomClosure = { .failure(.failedLeavingRoom) } room.leaveRoomClosure = { .failure(.sdkError(ClientProxyMockError.generic)) }
clientProxy.roomForIdentifierClosure = { _ in room } clientProxy.roomForIdentifierClosure = { _ in room }
@@ -138,7 +138,7 @@ class RoomDetailsScreenViewModelTests: XCTestCase {
defer { defer {
expectation.fulfill() expectation.fulfill()
} }
return .failure(.failedLeavingRoom) return .failure(.sdkError(ClientProxyMockError.generic))
} }
context.send(viewAction: .confirmLeave) context.send(viewAction: .confirmLeave)
await fulfillment(of: [expectation]) await fulfillment(of: [expectation])
@@ -207,7 +207,7 @@ class RoomDetailsScreenViewModelTests: XCTestCase {
let recipient = RoomMemberProxyMock.mockDan let recipient = RoomMemberProxyMock.mockDan
let mockedMembers: [RoomMemberProxyMock] = [.mockMe, recipient] let mockedMembers: [RoomMemberProxyMock] = [.mockMe, recipient]
let clientProxy = ClientProxyMock(.init()) let clientProxy = ClientProxyMock(.init())
clientProxy.ignoreUserReturnValue = .failure(.failedIgnoringUser) clientProxy.ignoreUserReturnValue = .failure(.sdkError(ClientProxyMockError.generic))
roomProxyMock = RoomProxyMock(with: .init(name: "Test", isDirect: true, isEncrypted: true, members: mockedMembers)) roomProxyMock = RoomProxyMock(with: .init(name: "Test", isDirect: true, isEncrypted: true, members: mockedMembers))
viewModel = RoomDetailsScreenViewModel(roomProxy: roomProxyMock, viewModel = RoomDetailsScreenViewModel(roomProxy: roomProxyMock,
clientProxy: clientProxy, clientProxy: clientProxy,
@@ -276,7 +276,7 @@ class RoomDetailsScreenViewModelTests: XCTestCase {
let recipient = RoomMemberProxyMock.mockIgnored let recipient = RoomMemberProxyMock.mockIgnored
let mockedMembers: [RoomMemberProxyMock] = [.mockMe, recipient] let mockedMembers: [RoomMemberProxyMock] = [.mockMe, recipient]
let clientProxy = ClientProxyMock(.init()) let clientProxy = ClientProxyMock(.init())
clientProxy.unignoreUserReturnValue = .failure(.failedUnignoringUser) clientProxy.unignoreUserReturnValue = .failure(.sdkError(ClientProxyMockError.generic))
roomProxyMock = RoomProxyMock(with: .init(name: "Test", isDirect: true, isEncrypted: true, members: mockedMembers)) roomProxyMock = RoomProxyMock(with: .init(name: "Test", isDirect: true, isEncrypted: true, members: mockedMembers))
viewModel = RoomDetailsScreenViewModel(roomProxy: roomProxyMock, viewModel = RoomDetailsScreenViewModel(roomProxy: roomProxyMock,
clientProxy: clientProxy, clientProxy: clientProxy,
@@ -87,7 +87,7 @@ class RoomMemberDetailsViewModelTests: XCTestCase {
func testIgnoreFailure() async throws { func testIgnoreFailure() async throws {
roomMemberProxyMock = RoomMemberProxyMock.mockAlice roomMemberProxyMock = RoomMemberProxyMock.mockAlice
let clientProxy = ClientProxyMock(.init()) let clientProxy = ClientProxyMock(.init())
clientProxy.ignoreUserReturnValue = .failure(.failedIgnoringUser) clientProxy.ignoreUserReturnValue = .failure(.sdkError(ClientProxyMockError.generic))
viewModel = RoomMemberDetailsScreenViewModel(userID: roomMemberProxyMock.userID, viewModel = RoomMemberDetailsScreenViewModel(userID: roomMemberProxyMock.userID,
roomProxy: roomProxyMock, roomProxy: roomProxyMock,
clientProxy: clientProxy, clientProxy: clientProxy,
@@ -158,7 +158,7 @@ class RoomMemberDetailsViewModelTests: XCTestCase {
func testUnignoreFailure() async throws { func testUnignoreFailure() async throws {
roomMemberProxyMock = RoomMemberProxyMock.mockIgnored roomMemberProxyMock = RoomMemberProxyMock.mockIgnored
let clientProxy = ClientProxyMock(.init()) let clientProxy = ClientProxyMock(.init())
clientProxy.unignoreUserReturnValue = .failure(.failedUnignoringUser) clientProxy.unignoreUserReturnValue = .failure(.sdkError(ClientProxyMockError.generic))
viewModel = RoomMemberDetailsScreenViewModel(userID: roomMemberProxyMock.userID, viewModel = RoomMemberDetailsScreenViewModel(userID: roomMemberProxyMock.userID,
roomProxy: roomProxyMock, roomProxy: roomProxyMock,
clientProxy: clientProxy, clientProxy: clientProxy,
@@ -71,7 +71,7 @@ class UserDiscoveryServiceTest: XCTestCase {
} }
func testLocalResultShowsOnSearchError() async { func testLocalResultShowsOnSearchError() async {
clientProxy.searchUsersSearchTermLimitReturnValue = .failure(.failedSearchingUsers) clientProxy.searchUsersSearchTermLimitReturnValue = .failure(.sdkError(ClientProxyMockError.generic))
clientProxy.profileForReturnValue = .success(.init(userID: "@some:matrix.org")) clientProxy.profileForReturnValue = .success(.init(userID: "@some:matrix.org"))
let results = await (try? search(query: "@a:b.com").get()) ?? [] let results = await (try? search(query: "@a:b.com").get()) ?? []
@@ -81,7 +81,7 @@ class UserDiscoveryServiceTest: XCTestCase {
} }
func testSearchErrorTriggers() async { func testSearchErrorTriggers() async {
clientProxy.searchUsersSearchTermLimitReturnValue = .failure(.failedSearchingUsers) clientProxy.searchUsersSearchTermLimitReturnValue = .failure(.sdkError(ClientProxyMockError.generic))
clientProxy.profileForReturnValue = .success(.init(userID: "@some:matrix.org")) clientProxy.profileForReturnValue = .success(.init(userID: "@some:matrix.org"))
switch await search(query: "some query") { switch await search(query: "some query") {
@@ -108,7 +108,7 @@ class UserDiscoveryServiceTest: XCTestCase {
func testSearchResultsShowWhenGetProfileFails() async { func testSearchResultsShowWhenGetProfileFails() async {
clientProxy.searchUsersSearchTermLimitReturnValue = .success(.init(results: searchResults, limited: true)) clientProxy.searchUsersSearchTermLimitReturnValue = .success(.init(results: searchResults, limited: true))
clientProxy.profileForReturnValue = .failure(.failedGettingUserProfile) clientProxy.profileForReturnValue = .failure(.sdkError(ClientProxyMockError.generic))
let results = await (try? search(query: "@a:b.com").get()) ?? [] let results = await (try? search(query: "@a:b.com").get()) ?? []