Skip to content

Commit

Permalink
feat: Add ErrorDomain for error handling
Browse files Browse the repository at this point in the history
  • Loading branch information
PhilippeWeidmann committed Oct 30, 2024
1 parent f99323e commit 352824c
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 21 deletions.
1 change: 1 addition & 0 deletions SwissTransferCore/Utils/KMP+Sendable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,4 @@ import STCore
// The following objects should be Sendable as discussed with the KMP team.
extension TransferUi: @retroactive @unchecked Sendable {}
extension FileUi: @retroactive @unchecked Sendable {}
extension NewUploadSession: @retroactive @unchecked Sendable {}
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,16 @@ class TransferSessionManager: ObservableObject {
minTotalChunks: 1
)

func startUpload(uploadSession: NewUploadSession) async {
enum ErrorDomain: Error {
case remoteContainerNotFound
case invalidURL(rawURL: String)
case invalidUploadChunkURL
case invalidRangeCompute
}

func startUpload(session newUploadSession: NewUploadSession) async throws -> String {
do {
overhaulProgress = Progress(totalUnitCount: Int64(uploadSession.files.count))
overhaulProgress = Progress(totalUnitCount: Int64(newUploadSession.files.count))
overhaulProgress?
.publisher(for: \.fractionCompleted)
.receive(on: RunLoop.main)
Expand All @@ -77,50 +84,51 @@ class TransferSessionManager: ObservableObject {

let uploadManager = injection.uploadManager

_ = try await uploadManager.createUpload(newUploadSession: uploadSession)

guard let upload = try await uploadManager.getLastUpload() else {
Logger.general.error("No remote container found")
return
}
let uploadSession = try await uploadManager.createUpload(newUploadSession: newUploadSession)

try await uploadManager.doInitUploadSession(uuid: upload.uuid, recaptcha: "aabb")
let uploadWithRemoteContainer = try await uploadManager.doInitUploadSession(
uuid: uploadSession.uuid,
recaptcha: "aabb"
)

guard let uploadWithRemoteContainer = try await uploadManager.getLastUpload(),
guard let uploadWithRemoteContainer,
let container = uploadWithRemoteContainer.remoteContainer else {
Logger.general.error("No remote container found")
return
throw ErrorDomain.remoteContainerNotFound
}

let remoteUploadFiles = uploadWithRemoteContainer.files.compactMap { $0.remoteUploadFile }
assert(remoteUploadFiles.count == uploadWithRemoteContainer.files.count, "Cast should always success")
assert(remoteUploadFiles.count == uploadWithRemoteContainer.files.count, "All files should have a remote upload file")

for (index, remoteUploadFile) in remoteUploadFiles.enumerated() {
let localFile = uploadWithRemoteContainer.files[index]

try await uploadFile(atPath: localFile.localPath, toRemoteFile: remoteUploadFile, uploadUUID: upload.uuid)
try await uploadFile(atPath: localFile.localPath, toRemoteFile: remoteUploadFile, uploadUUID: uploadSession.uuid)
}

Logger.general.info("Found container: \(container.uuid)")

try await uploadManager.finishUploadSession(uuid: upload.uuid)
let transferUUID = try await uploadManager.finishUploadSession(uuid: uploadSession.uuid)

return transferUUID
} catch let error as RecaptchaError {
Logger.general.error("Recaptcha client error: \(error.errorMessage ?? "")")
fatalError("Implement error handling")
} catch {
Logger.general.error("Error trying to start upload: \(error)")
fatalError("Implement error handling")
}
}

private func uploadFile(atPath: String, toRemoteFile: any RemoteUploadFile, uploadUUID: String) async throws {
guard let fileURL = URL(string: atPath) else {
fatalError("Wrong path")
throw ErrorDomain.invalidURL(rawURL: atPath)
}

let rangeProvider = RangeProvider(fileURL: fileURL, config: TransferSessionManager.rangeProviderConfig)

let ranges = try rangeProvider.allRanges
guard let chunkProvider = ChunkProvider(fileURL: fileURL, ranges: ranges) else {
fatalError("Couldn't compute ranges")
throw ErrorDomain.invalidRangeCompute
}

let rangeCount = ranges.count
Expand All @@ -129,14 +137,20 @@ class TransferSessionManager: ObservableObject {

var index: Int32 = 0
while let chunk = chunkProvider.next() {
let chunkURL = try injection.sharedApiUrlCreator.uploadChunkUrl(
guard let rawChunkURL = try injection.sharedApiUrlCreator.uploadChunkUrl(
uploadUUID: uploadUUID,
fileUUID: toRemoteFile.uuid,
chunkIndex: index,
isLastChunk: index == rangeCount - 1
)!
) else {
throw ErrorDomain.invalidUploadChunkURL
}

guard let chunkURL = URL(string: rawChunkURL) else {
throw ErrorDomain.invalidURL(rawURL: rawChunkURL)
}

var uploadRequest = URLRequest(url: URL(string: chunkURL)!)
var uploadRequest = URLRequest(url: chunkURL)
uploadRequest.httpMethod = "POST"

let taskDelegate = UploadTaskDelegate(totalBytesExpectedToSend: chunk.count)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,12 @@ import SwiftUI
import SwissTransferCore

public struct UploadProgressView: View {
@EnvironmentObject private var transferManager: TransferManager

@StateObject private var transferSessionManager = TransferSessionManager()

@State private var error: Error?

let uploadSession: NewUploadSession

public init(uploadSession: NewUploadSession) {
Expand All @@ -36,7 +40,16 @@ public struct UploadProgressView: View {
}
.onAppear {
Task {
await transferSessionManager.startUpload(uploadSession: uploadSession)
do {
let transferUUID = try await transferSessionManager.startUpload(session: uploadSession)
guard let transfer = transferManager.getTransferByUUID(transferUUID: transferUUID) else {
fatalError("Couldn't find transfer")
}

// TODO: Navigate to transfer
} catch {
self.error = error
}
}
}
}
Expand Down

0 comments on commit 352824c

Please sign in to comment.