aboutsummaryrefslogtreecommitdiff
path: root/Hotline
diff options
context:
space:
mode:
authorDustin Mierau <dustin@mierau.me>2025-11-13 11:13:01 -0800
committerDustin Mierau <dustin@mierau.me>2025-11-13 11:13:01 -0800
commit467b53f143a0c3d7328fe85e9d1215eceb9b150a (patch)
treee8db83720021bc9361732d06ff539fcd42d72def /Hotline
parent5818df427f045f3aa54f648a0828c8d997327fbe (diff)
Start surfacing server errors properly to communicate permissions better.
Diffstat (limited to 'Hotline')
-rw-r--r--Hotline/Hotline/HotlineClient.swift10
-rw-r--r--Hotline/State/HotlineState.swift32
-rw-r--r--Hotline/macOS/Files/FilesView.swift16
-rw-r--r--Hotline/macOS/Files/FolderItemView.swift4
-rw-r--r--Hotline/macOS/ServerView.swift7
5 files changed, 44 insertions, 25 deletions
diff --git a/Hotline/Hotline/HotlineClient.swift b/Hotline/Hotline/HotlineClient.swift
index 8d0e870..7305a2f 100644
--- a/Hotline/Hotline/HotlineClient.swift
+++ b/Hotline/Hotline/HotlineClient.swift
@@ -429,6 +429,7 @@ public actor HotlineClient {
} catch is TaskTimeoutError {
throw HotlineClientError.timeout
} catch let error as HotlineClientError {
+ print("Hotline Client Error: \(error)")
throw error
} catch {
throw error
@@ -651,17 +652,12 @@ public actor HotlineClient {
/// - name: File or folder name
/// - path: Directory path containing the item
/// - Returns: True if deletion succeeded
- public func deleteFile(name: String, path: [String]) async throws -> Bool {
+ public func deleteFile(name: String, path: [String]) async throws {
var transaction = HotlineTransaction(id: self.generateTransactionID(), type: .deleteFile)
transaction.setFieldString(type: .fileName, val: name)
transaction.setFieldPath(type: .filePath, val: path)
- do {
- try await self.sendTransaction(transaction)
- return true
- } catch {
- return false
- }
+ try await self.sendTransaction(transaction)
}
/// Create a folder
diff --git a/Hotline/State/HotlineState.swift b/Hotline/State/HotlineState.swift
index 627b6a0..1f8e2e5 100644
--- a/Hotline/State/HotlineState.swift
+++ b/Hotline/State/HotlineState.swift
@@ -799,7 +799,7 @@ class HotlineState: Equatable {
self.users = hotlineUsers.map { User(hotlineUser: $0) }
}
- // MARK: - Files (Basic)
+ // MARK: - Files
@MainActor
@discardableResult
@@ -856,7 +856,7 @@ class HotlineState: Equatable {
}
@MainActor
- func deleteFile(_ fileName: String, path: [String]) async throws -> Bool {
+ func deleteFile(_ fileName: String, path: [String]) async throws {
guard let client = self.client else {
throw HotlineClientError.notConnected
}
@@ -865,14 +865,16 @@ class HotlineState: Equatable {
if path.count > 1 {
fullPath = Array(path[0..<path.count-1])
}
-
- let success = try await client.deleteFile(name: fileName, path: fullPath)
-
- if success {
+
+ do {
+ try await client.deleteFile(name: fileName, path: fullPath)
self.invalidateFileListCache(for: fullPath, includingAncestors: true)
}
-
- return success
+ catch let error as HotlineClientError {
+ self.errorMessage = error.userMessage
+ self.errorDisplayed = true
+ return
+ }
}
/// Download a file from the server.
@@ -1280,9 +1282,21 @@ class HotlineState: Equatable {
Task { @MainActor [weak self] in
guard let self else { return }
+
+ let referenceNumber: UInt32?
+
+ do {
+ referenceNumber = try await client.uploadFile(name: fileName, path: path)
+ }
+ catch let error as HotlineClientError {
+ self.errorMessage = error.userMessage
+ self.errorDisplayed = true
+ return
+ }
+
// Request upload from server
- guard let referenceNumber = try? await client.uploadFile(name: fileName, path: path),
+ guard let referenceNumber,
let server = self.server,
let address = server.address as String?,
let port = server.port as Int?
diff --git a/Hotline/macOS/Files/FilesView.swift b/Hotline/macOS/Files/FilesView.swift
index 2386d2a..ab93cbc 100644
--- a/Hotline/macOS/Files/FilesView.swift
+++ b/Hotline/macOS/Files/FilesView.swift
@@ -448,14 +448,14 @@ struct FilesView: View {
@MainActor private func downloadFile(_ file: FileInfo) {
if file.isFolder {
- model.downloadFolder(file.name, path: file.path)
+ self.model.downloadFolder(file.name, path: file.path)
}
else {
- model.downloadFile(file.name, path: file.path)
+ self.model.downloadFile(file.name, path: file.path)
}
}
- @MainActor private func uploadFile(file fileURL: URL, to path: [String]) {
+ @MainActor private func uploadFile(file fileURL: URL, to path: [String]) throws {
self.model.uploadFile(url: fileURL, path: path) { info in
Task {
// Refresh file listing to display newly uploaded file.
@@ -508,9 +508,13 @@ struct FilesView: View {
if file.path.count > 1 {
parentPath = Array(file.path[0..<file.path.count-1])
}
-
- if (try? await model.deleteFile(file.name, path: file.path)) == true {
- let _ = try? await model.getFileList(path: parentPath)
+
+ do {
+ try await self.model.deleteFile(file.name, path: file.path)
+ try await self.model.getFileList(path: parentPath)
+ }
+ catch {
+ print("Error deleting file: \(error)")
}
}
}
diff --git a/Hotline/macOS/Files/FolderItemView.swift b/Hotline/macOS/Files/FolderItemView.swift
index 9b13cc0..18522af 100644
--- a/Hotline/macOS/Files/FolderItemView.swift
+++ b/Hotline/macOS/Files/FolderItemView.swift
@@ -17,7 +17,7 @@ struct FolderItemView: View {
print("UPLOADING TO PATH: ", filePath)
- model.uploadFile(url: fileURL, path: filePath) { info in
+ self.model.uploadFile(url: fileURL, path: filePath) { info in
Task {
// Refresh file listing to display newly uploaded file.
let _ = try? await model.getFileList(path: filePath)
@@ -118,7 +118,7 @@ struct FolderItemView: View {
DispatchQueue.main.async {
if let urlData = urlData as? Data,
let fileURL = URL(dataRepresentation: urlData, relativeTo: nil, isAbsolute: true) {
- uploadFile(file: fileURL)
+ self.uploadFile(file: fileURL)
}
}
}
diff --git a/Hotline/macOS/ServerView.swift b/Hotline/macOS/ServerView.swift
index 6184749..1f85bd7 100644
--- a/Hotline/macOS/ServerView.swift
+++ b/Hotline/macOS/ServerView.swift
@@ -196,8 +196,13 @@ struct ServerView: View {
.onChange(of: self.model.serverTitle) {
self.state.serverName = self.model.serverTitle
}
- .alert(self.model.errorMessage ?? "Server Error", isPresented: self.$model.errorDisplayed) {
+ .alert("Something Went Wrong", isPresented: self.$model.errorDisplayed) {
Button("OK") {}
+ } message: {
+ if let message = self.model.errorMessage,
+ !message.isBlank {
+ Text(message)
+ }
}
.onAppear {
var address = self.server.address