From 7973da825178854f9f1f158820abae43ac717dd0 Mon Sep 17 00:00:00 2001 From: Stefan Ceriu Date: Wed, 30 Sep 2026 11:36:06 +0300 Subject: [PATCH] Throw from session directories and only fatal error when making sense. --- .../Authentication/AuthenticationService.swift | 2 +- .../Services/UserSession/SessionDirectories.swift | 13 +++++++++---- .../Services/UserSession/UserSessionStore.swift | 8 ++++++-- UnitTests/Sources/SessionDirectoriesTests.swift | 6 +++--- UnitTests/Sources/UserSessionStoreTests.swift | 4 ++-- 5 files changed, 21 insertions(+), 12 deletions(-) diff --git a/ElementX/Sources/Services/Authentication/AuthenticationService.swift b/ElementX/Sources/Services/Authentication/AuthenticationService.swift index 81ea92bc7..b822348f6 100644 --- a/ElementX/Sources/Services/Authentication/AuthenticationService.swift +++ b/ElementX/Sources/Services/Authentication/AuthenticationService.swift @@ -280,7 +280,7 @@ class AuthenticationService: AuthenticationServiceProtocol { } private func rotateSessionDirectory() { - sessionDirectories.delete() + try? sessionDirectories.delete() sessionDirectories = .init() } diff --git a/ElementX/Sources/Services/UserSession/SessionDirectories.swift b/ElementX/Sources/Services/UserSession/SessionDirectories.swift index 9f59d0c0c..8f41bad3a 100644 --- a/ElementX/Sources/Services/UserSession/SessionDirectories.swift +++ b/ElementX/Sources/Services/UserSession/SessionDirectories.swift @@ -23,37 +23,42 @@ nonisolated struct SessionDirectories: Hashable, Codable { // MARK: Data Management /// Removes the directories from disk if they have been created. - func delete() { + func delete() throws { do { if FileManager.default.directoryExists(at: dataDirectory) { try FileManager.default.removeItem(at: dataDirectory) } } catch { - MXLog.failure("Failed deleting the session data: \(error)") + MXLog.error("Failed deleting the session data: \(error)") + throw error } + do { if FileManager.default.directoryExists(at: cacheDirectory) { try FileManager.default.removeItem(at: cacheDirectory) } } catch { - MXLog.failure("Failed deleting the session caches: \(error)") + MXLog.error("Failed deleting the session caches: \(error)") + throw error } } /// Deletes the Rust state store and event cache data, leaving the crypto store and both /// session directories in place along with any other data that may have been written in them. - func deleteTransientUserData() { + func deleteTransientUserData() throws { do { let prefix = "matrix-sdk-state" try deleteFiles(at: dataDirectory, with: prefix) } catch { MXLog.failure("Failed clearing state store: \(error)") + throw error } do { let prefix = "matrix-sdk-event-cache" try deleteFiles(at: cacheDirectory, with: prefix) } catch { MXLog.failure("Failed clearing event cache store: \(error)") + throw error } } diff --git a/ElementX/Sources/Services/UserSession/UserSessionStore.swift b/ElementX/Sources/Services/UserSession/UserSessionStore.swift index 99ab6e7e5..e9ff464ff 100644 --- a/ElementX/Sources/Services/UserSession/UserSessionStore.swift +++ b/ElementX/Sources/Services/UserSession/UserSessionStore.swift @@ -69,7 +69,11 @@ class UserSessionStore: UserSessionStoreProtocol { // On any restoration failure reset the token and restart keychainController.removeRestorationTokenForUsername(credentials.userID) - credentials.restorationToken.sessionDirectories.delete() + do { + try credentials.restorationToken.sessionDirectories.delete() + } catch { + fatalError("Failed deleting session directories with error \(error)") + } return .failure(error) } @@ -103,7 +107,7 @@ class UserSessionStore: UserSessionStoreProtocol { keychainController.removeRestorationTokenForUsername(userID) if let credentials { - credentials.restorationToken.sessionDirectories.delete() + try? credentials.restorationToken.sessionDirectories.delete() } } diff --git a/UnitTests/Sources/SessionDirectoriesTests.swift b/UnitTests/Sources/SessionDirectoriesTests.swift index be81bfd4e..d05a53159 100644 --- a/UnitTests/Sources/SessionDirectoriesTests.swift +++ b/UnitTests/Sources/SessionDirectoriesTests.swift @@ -55,7 +55,7 @@ struct SessionDirectoriesTests { #expect(fileManager.directoryExists(at: sessionDirectories.cacheDirectory)) // When deleting the directories. - sessionDirectories.delete() + try? sessionDirectories.delete() // Then neither directory should exist on disk. #expect(!fileManager.directoryExists(at: sessionDirectories.dataDirectory)) @@ -79,7 +79,7 @@ struct SessionDirectoriesTests { #expect(try fileManager.numberOfItems(at: sessionDirectories.cacheDirectory) == 3) // When deleting transient user data. - sessionDirectories.deleteTransientUserData() + try? sessionDirectories.deleteTransientUserData() // Then the data directory should only contain the crypto store and the cache directory should remain but be empty. #expect(fileManager.directoryExists(at: sessionDirectories.dataDirectory)) @@ -92,6 +92,6 @@ struct SessionDirectoriesTests { #expect(!fileManager.fileExists(atPath: sessionDirectories.mockEventCachePath)) // The tests are done, tidy up these useless directories 🧹 - sessionDirectories.delete() + try? sessionDirectories.delete() } } diff --git a/UnitTests/Sources/UserSessionStoreTests.swift b/UnitTests/Sources/UserSessionStoreTests.swift index 1d8fb27ef..493dbf2d2 100644 --- a/UnitTests/Sources/UserSessionStoreTests.swift +++ b/UnitTests/Sources/UserSessionStoreTests.swift @@ -73,7 +73,7 @@ struct UserSessionStoreTests { func restoreWhenClientCreationFails() async throws { // Given valid session data but a client factory that fails. let sessionDirectories = try makeValidSessionDirectories() - defer { sessionDirectories.delete() } + defer { try? sessionDirectories.delete() } let credentials = makeCredentials(sessionDirectories: sessionDirectories) keychainController.restorationTokensReturnValue = [credentials] clientFactory.makeAppClientCredentialsClientSessionDelegateAppSettingsAppHooksThrowableError = TestError.generic @@ -92,7 +92,7 @@ struct UserSessionStoreTests { func restoreSucceeds() async throws { // Given valid session data and a client factory that returns a client. let sessionDirectories = try makeValidSessionDirectories() - defer { sessionDirectories.delete() } + defer { try? sessionDirectories.delete() } keychainController.restorationTokensReturnValue = [makeCredentials(sessionDirectories: sessionDirectories)] // When restoring the session.